ATLAS-1894: Search using entity/tag attribute filters

Signed-off-by: Madhan Neethiraj <madhan@apache.org>
diff --git a/3party-licenses/bootstrap-daterangepicker-LICENSE b/3party-licenses/bootstrap-daterangepicker-LICENSE
new file mode 100644
index 0000000..aacee25
--- /dev/null
+++ b/3party-licenses/bootstrap-daterangepicker-LICENSE
@@ -0,0 +1,9 @@
+The MIT License (MIT)
+
+Copyright (c) 2012-2017 Dan Grossman
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
diff --git a/3party-licenses/bootstrap-datepicker-LICENSE b/3party-licenses/jQuery-QueryBuilder-LICENSE
similarity index 95%
rename from 3party-licenses/bootstrap-datepicker-LICENSE
rename to 3party-licenses/jQuery-QueryBuilder-LICENSE
index 3fd94fa..99070e3 100644
--- a/3party-licenses/bootstrap-datepicker-LICENSE
+++ b/3party-licenses/jQuery-QueryBuilder-LICENSE
@@ -1,6 +1,6 @@
 The MIT License (MIT)
 
-Copyright (c) 2015 Jonathan Peterson (@Eonasdan)
+Copyright (c) 2014-2015 Damien Sorel
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
diff --git a/LICENSE b/LICENSE
index 9722907..435e340 100755
--- a/LICENSE
+++ b/LICENSE
@@ -248,9 +248,12 @@
 This product bundles Respond, which is available under
 MIT License. For details, see 3party-licenses/Respond-LICENSE
 
-This product bundles bootstrap-datepicker 4.14.30, which is available under
-MIT License.  For details, see 3party-licenses/bootstrap-datepicker-LICENSE
-
 This product bundles Google Fonts, which are available under
 Open Font License.  For details, see 3party-licenses/google-fonts-LICENSE
+
+This product bundles bootstrap-daterangepicker 2.1.25, which is available under
+MIT License.  For details, see 3party-licenses/bootstrap-daterangepicker-LICENSE
+
+This product bundles jQuery QueryBuilder 2.4.3, which is available under
+MIT License.  For details, see 3party-licenses/jQuery-QueryBuilder-LICENSE
 =======================================================================
diff --git a/dashboardv2/gruntfile.js b/dashboardv2/gruntfile.js
index cf076b6..c0e315f 100644
--- a/dashboardv2/gruntfile.js
+++ b/dashboardv2/gruntfile.js
@@ -32,9 +32,6 @@
         modulesPath = '../public/'
     }
 
-    var proxySnippet = require('grunt-connect-proxy/lib/utils').proxyRequest;
-
-
     grunt.initConfig({
         watch: {
             js: {
@@ -130,7 +127,9 @@
                     'backgrid-select-all': 'backgrid-select-all/backgrid-select-all.min.js',
                     'moment/js': 'moment/min/moment.min.js',
                     'jquery-placeholder/js': 'jquery-placeholder/jquery.placeholder.js',
-                    'platform': 'platform/platform.js'
+                    'platform': 'platform/platform.js',
+                    'jQueryQueryBuilder/js': 'jQuery-QueryBuilder/dist/js/query-builder.standalone.min.js',
+                    'bootstrap-daterangepicker/js': 'bootstrap-daterangepicker/daterangepicker.js'
                 }
             },
             css: {
@@ -149,7 +148,9 @@
                     'select2/css': 'select2/dist/css/select2.min.css',
                     'backgrid-select-all': 'backgrid-select-all/backgrid-select-all.min.css',
                     'font-awesome/css': 'font-awesome/css/font-awesome.min.css',
-                    'font-awesome/fonts': 'font-awesome/fonts'
+                    'font-awesome/fonts': 'font-awesome/fonts',
+                    'jQueryQueryBuilder/css': 'jQuery-QueryBuilder/dist/css/query-builder.default.min.css',
+                    'bootstrap-daterangepicker/css': 'bootstrap-daterangepicker/daterangepicker.css'
                 }
 
             },
@@ -177,13 +178,19 @@
                     'dagre-d3': 'dagre-d3/LICENSE',
                     'backgrid-select-all': 'backgrid-select-all/LICENSE-MIT',
                     'jquery-placeholder': 'jquery-placeholder/LICENSE.txt',
-                    'platform/': 'platform/LICENSE'
+                    'platform/': 'platform/LICENSE',
+                    'jQueryQueryBuilder/': 'jQuery-QueryBuilder/LICENSE'
                 }
             }
         },
         sass: {
             dist: {
                 files: {
+                    'dist/css/style.css': 'public/css/scss/style.scss'
+                }
+            },
+            build: {
+                files: {
                     'dist/css/style.css': 'dist/css/scss/style.scss'
                 }
             }
@@ -192,7 +199,13 @@
             dist: {
                 expand: true,
                 cwd: modulesPath,
-                src: ['**', '!**/*.sass'],
+                src: ['**', '!**/scss/**'],
+                dest: distPath
+            },
+            build: {
+                expand: true,
+                cwd: modulesPath,
+                src: ['**'],
                 dest: distPath
             }
         },
@@ -201,6 +214,41 @@
             options: {
                 force: true
             }
+        },
+        uglify: {
+            build: {
+                files: [{
+                    expand: true,
+                    cwd: 'dist/js',
+                    src: '**/*.js',
+                    dest: 'dist/js'
+                }]
+            }
+        },
+        cssmin: {
+            build: {
+                files: [{
+                    expand: true,
+                    cwd: 'dist/css',
+                    src: '*.css',
+                    dest: 'dist/css'
+                }]
+            }
+
+        },
+        htmlmin: {
+            build: {
+                options: {
+                    removeComments: true,
+                    collapseWhitespace: true
+                },
+                files: [{
+                    expand: true,
+                    cwd: 'dist/js/templates',
+                    src: '**/*.html',
+                    dest: 'dist/js/templates'
+                }]
+            }
         }
     });
 
@@ -208,7 +256,9 @@
     grunt.loadNpmTasks('grunt-contrib-connect');
     grunt.loadNpmTasks('grunt-contrib-watch');
     grunt.loadNpmTasks('grunt-npmcopy');
-
+    grunt.loadNpmTasks('grunt-contrib-uglify');
+    grunt.loadNpmTasks('grunt-contrib-cssmin');
+    grunt.loadNpmTasks('grunt-contrib-htmlmin');
 
     require('load-grunt-tasks')(grunt);
 
@@ -226,33 +276,45 @@
         'npmcopy:css',
         'npmcopy:license',
         'copy:dist',
-        'sass',
+        'sass:dist',
         'configureProxies:server',
         'connect:server',
-        /* 'concurrent',*/
-        'watch',
-        /*'connect:livereload'*/
+        'watch'
     ]);
 
     grunt.registerTask('build', [
+        'clean',
+        'npmcopy:js',
+        'npmcopy:css',
+        'npmcopy:license',
+        'copy:build',
+        'sass:build'
+    ]);
+
+    grunt.registerTask('dev-minify', [
+        'clean',
         'npmcopy:js',
         'npmcopy:css',
         'npmcopy:license',
         'copy:dist',
-        'sass'
+        'sass:dist',
+        'uglify:build',
+        'cssmin:build',
+        'htmlmin:build',
+        'configureProxies:server',
+        'connect:server',
+        'watch'
     ]);
 
-    grunt.registerTask('minify', 'Minify the all js', function() {
-        var done = this.async();
-        grunt.task.run(['shell:min']);
-        done();
-    });
-    grunt.registerTask('release', 'Create release package', function() {
-        var done = this.async();
-        git.short(function(str) {
-            gitHash = str;
-            grunt.task.run(['minify', 'compress:release']);
-            done();
-        });
-    });
+    grunt.registerTask('build-minify', [
+        'clean',
+        'npmcopy:js',
+        'npmcopy:css',
+        'npmcopy:license',
+        'copy:build',
+        'sass:build',
+        'uglify:build',
+        'cssmin:build',
+        'htmlmin:build'
+    ]);
 };
diff --git a/dashboardv2/package.json b/dashboardv2/package.json
index 8924f71..59889d3 100644
--- a/dashboardv2/package.json
+++ b/dashboardv2/package.json
@@ -28,10 +28,12 @@
     "backgrid-select-all": "^0.3.5",
     "backgrid-sizeable-columns": "^0.1.1",
     "bootstrap": "^3.3.5",
+    "bootstrap-daterangepicker": "^2.1.25",
     "d3": "^3.5.16",
     "d3-tip": "^0.6.7",
     "dagre-d3": "^0.4.17",
     "font-awesome": "^4.6.3",
+    "jQuery-QueryBuilder": "^2.4.3",
     "jquery": "^2.2.2",
     "jquery-asBreadcrumbs": "^0.2.1",
     "jquery-placeholder": "^2.3.1",
@@ -55,7 +57,10 @@
     "grunt-contrib-compress": "^0.13.0",
     "grunt-contrib-connect": "^1.0.0",
     "grunt-contrib-copy": "~0.8.0",
+    "grunt-contrib-cssmin": "^2.0.0",
+    "grunt-contrib-htmlmin": "^2.2.0",
     "grunt-contrib-jshint": "^0.11.0",
+    "grunt-contrib-uglify": "^2.1.0",
     "grunt-contrib-watch": "^0.6.1",
     "grunt-dev-update": "^1.0.2",
     "grunt-jsbeautifier": "^0.2.6",
diff --git a/dashboardv2/public/css/scss/form.scss b/dashboardv2/public/css/scss/form.scss
index 3ee94f5..9989e7c 100644
--- a/dashboardv2/public/css/scss/form.scss
+++ b/dashboardv2/public/css/scss/form.scss
@@ -166,6 +166,10 @@
     margin-bottom: 10px;
     border-radius: 4px;
     padding: 5px 10px;
+    &.active {
+        background-color: $color_keppel_approx;
+        color: $white;
+    }
     &:hover {
         background-color: $color_keppel_approx;
         color: $white;
diff --git a/dashboardv2/public/css/scss/override.scss b/dashboardv2/public/css/scss/override.scss
index 2852f80..6821d77 100644
--- a/dashboardv2/public/css/scss/override.scss
+++ b/dashboardv2/public/css/scss/override.scss
@@ -46,6 +46,7 @@
     position: relative;
     padding: 15px;
     max-height: 400px;
+    min-height: 70px;
     overflow: auto;
 }
 
@@ -265,3 +266,23 @@
     margin-left: 5px;
     cursor: pointer;
 }
+
+.query-builder .rule-container .rule-value-container {
+    display: inline-block !important;
+}
+
+.rules-group-header .btn-group.pull-right.group-actions {
+    float: left !important;
+}
+
+.query-builder .rules-list>:first-child::before {
+    top: -8px;
+}
+
+.query-builder .rules-group-header .btn-group.group-conditions label {
+    display: none;
+}
+
+.query-builder .rule-value-container input {
+    padding: 6px 12px !important;
+}
diff --git a/dashboardv2/public/css/scss/search.scss b/dashboardv2/public/css/scss/search.scss
index 8c3dbec..2bce210 100644
--- a/dashboardv2/public/css/scss/search.scss
+++ b/dashboardv2/public/css/scss/search.scss
@@ -114,3 +114,20 @@
         color: $gray
     }
 }
+
+.filterQuery {
+    word-break: break-all;
+    span {
+        font-size: 15px;
+        font-weight: bold;
+    }
+    .key {
+        color: $color_jungle_green_approx;
+    }
+    .operator {
+        color: $action_gray;
+    }
+    .value {
+        color: $tag_color;
+    }
+}
diff --git a/dashboardv2/public/index.html b/dashboardv2/public/index.html
index 5fff304..b460686 100644
--- a/dashboardv2/public/index.html
+++ b/dashboardv2/public/index.html
@@ -45,12 +45,13 @@
     <link rel="stylesheet" href="js/libs/select2/css/select2.min.css">
     <link rel="stylesheet" href="js/libs/bootstrap/css/bootstrap.min.css">
     <link rel="stylesheet" href="js/libs/jquery-asBreadcrumbs/css/asBreadcrumbs.min.css">
-    <link rel="stylesheet" href="js/external_lib/datetimepicker/bootstrap-datetimepicker.min.css">
     <link rel="stylesheet" href="css/googlefonts.css" type='text/css'>
     <link rel="stylesheet" type="text/css" href="js/external_lib/jquery-ui/jquery-ui.min.css">
     <link href="css/bootstrap-sidebar.css" rel="stylesheet">
     <link href="js/libs/font-awesome/css/font-awesome.min.css" rel="stylesheet">
     <link href="js/external_lib/pnotify/pnotify.custom.min.css" rel="stylesheet">
+    <link href="js/libs/jQueryQueryBuilder/css/query-builder.default.min.css" rel="stylesheet">
+    <link href="js/libs/bootstrap-daterangepicker/css/daterangepicker.css" rel="stylesheet">
     <link href="css/style.css" rel="stylesheet">
 </head>
 
diff --git a/dashboardv2/public/js/collection/VSearchList.js b/dashboardv2/public/js/collection/VSearchList.js
index 6a84943..6291838 100644
--- a/dashboardv2/public/js/collection/VSearchList.js
+++ b/dashboardv2/public/js/collection/VSearchList.js
@@ -39,6 +39,17 @@
                 this.queryText = resp.queryText;
                 return resp.entities ? resp.entities : [];
             },
+            getBasicRearchResult: function(options) {
+                var url = UrlLinks.searchApiUrl('basic');
+
+                options = _.extend({
+                    contentType: 'application/json',
+                    dataType: 'json',
+                }, options);
+                options.data = JSON.stringify(options.data);
+
+                return this.constructor.nonCrudOperation.call(this, url, 'POST', options);
+            }
         },
         //Static Class Members
         {
diff --git a/dashboardv2/public/js/collection/VTagList.js b/dashboardv2/public/js/collection/VTagList.js
index 9304858..146fd10 100644
--- a/dashboardv2/public/js/collection/VTagList.js
+++ b/dashboardv2/public/js/collection/VTagList.js
@@ -26,7 +26,7 @@
     var VTagList = BaseCollection.extend(
         //Prototypal attributes
         {
-            url: UrlLinks.typesClassicationApiUrl(),
+            url: UrlLinks.classificationDefApiUrl(),
             model: VTag,
             initialize: function() {
                 this.modelName = 'VTag';
diff --git a/dashboardv2/public/js/external_lib/datetimepicker/bootstrap-datetimepicker.js b/dashboardv2/public/js/external_lib/datetimepicker/bootstrap-datetimepicker.js
deleted file mode 100644
index bb930fb..0000000
--- a/dashboardv2/public/js/external_lib/datetimepicker/bootstrap-datetimepicker.js
+++ /dev/null
@@ -1,2444 +0,0 @@
-/*! version : 4.14.30
- =========================================================
- bootstrap-datetimejs
- https://github.com/Eonasdan/bootstrap-datetimepicker
- Copyright (c) 2015 Jonathan Peterson
- =========================================================
- */
-/*
- The MIT License (MIT)
-
- Copyright (c) 2015 Jonathan Peterson
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
- */
-/*global define:false */
-/*global exports:false */
-/*global require:false */
-/*global jQuery:false */
-/*global moment:false */
-(function (factory) {
-    'use strict';
-    if (typeof define === 'function' && define.amd) {
-        // AMD is used - Register as an anonymous module.
-        define(['jquery', 'moment'], factory);
-    } else if (typeof exports === 'object') {
-        factory(require('jquery'), require('moment'));
-    } else {
-        // Neither AMD nor CommonJS used. Use global variables.
-        if (typeof jQuery === 'undefined') {
-            throw 'bootstrap-datetimepicker requires jQuery to be loaded first';
-        }
-        if (typeof moment === 'undefined') {
-            throw 'bootstrap-datetimepicker requires Moment.js to be loaded first';
-        }
-        factory(jQuery, moment);
-    }
-}(function ($, moment) {
-    'use strict';
-    if (!moment) {
-        throw new Error('bootstrap-datetimepicker requires Moment.js to be loaded first');
-    }
-
-    var dateTimePicker = function (element, options) {
-        var picker = {},
-            date = moment().startOf('d'),
-            viewDate = date.clone(),
-            unset = true,
-            input,
-            component = false,
-            widget = false,
-            use24Hours,
-            minViewModeNumber = 0,
-            actualFormat,
-            parseFormats,
-            currentViewMode,
-            datePickerModes = [
-                {
-                    clsName: 'days',
-                    navFnc: 'M',
-                    navStep: 1
-                },
-                {
-                    clsName: 'months',
-                    navFnc: 'y',
-                    navStep: 1
-                },
-                {
-                    clsName: 'years',
-                    navFnc: 'y',
-                    navStep: 10
-                },
-                {
-                    clsName: 'decades',
-                    navFnc: 'y',
-                    navStep: 100
-                }
-            ],
-            viewModes = ['days', 'months', 'years', 'decades'],
-            verticalModes = ['top', 'bottom', 'auto'],
-            horizontalModes = ['left', 'right', 'auto'],
-            toolbarPlacements = ['default', 'top', 'bottom'],
-            keyMap = {
-                'up': 38,
-                38: 'up',
-                'down': 40,
-                40: 'down',
-                'left': 37,
-                37: 'left',
-                'right': 39,
-                39: 'right',
-                'tab': 9,
-                9: 'tab',
-                'escape': 27,
-                27: 'escape',
-                'enter': 13,
-                13: 'enter',
-                'pageUp': 33,
-                33: 'pageUp',
-                'pageDown': 34,
-                34: 'pageDown',
-                'shift': 16,
-                16: 'shift',
-                'control': 17,
-                17: 'control',
-                'space': 32,
-                32: 'space',
-                't': 84,
-                84: 't',
-                'delete': 46,
-                46: 'delete'
-            },
-            keyState = {},
-
-            /********************************************************************************
-             *
-             * Private functions
-             *
-             ********************************************************************************/
-            isEnabled = function (granularity) {
-                if (typeof granularity !== 'string' || granularity.length > 1) {
-                    throw new TypeError('isEnabled expects a single character string parameter');
-                }
-                switch (granularity) {
-                    case 'y':
-                        return actualFormat.indexOf('Y') !== -1;
-                    case 'M':
-                        return actualFormat.indexOf('M') !== -1;
-                    case 'd':
-                        return actualFormat.toLowerCase().indexOf('d') !== -1;
-                    case 'h':
-                    case 'H':
-                        return actualFormat.toLowerCase().indexOf('h') !== -1;
-                    case 'm':
-                        return actualFormat.indexOf('m') !== -1;
-                    case 's':
-                        return actualFormat.indexOf('s') !== -1;
-                    default:
-                        return false;
-                }
-            },
-            hasTime = function () {
-                return (isEnabled('h') || isEnabled('m') || isEnabled('s'));
-            },
-
-            hasDate = function () {
-                return (isEnabled('y') || isEnabled('M') || isEnabled('d'));
-            },
-
-            getDatePickerTemplate = function () {
-                var headTemplate = $('<thead>')
-                        .append($('<tr>')
-                            .append($('<th>').addClass('prev').attr('data-action', 'previous')
-                                .append($('<span>').addClass(options.icons.previous))
-                                )
-                            .append($('<th>').addClass('picker-switch').attr('data-action', 'pickerSwitch').attr('colspan', (options.calendarWeeks ? '6' : '5')))
-                            .append($('<th>').addClass('next').attr('data-action', 'next')
-                                .append($('<span>').addClass(options.icons.next))
-                                )
-                            ),
-                    contTemplate = $('<tbody>')
-                        .append($('<tr>')
-                            .append($('<td>').attr('colspan', (options.calendarWeeks ? '8' : '7')))
-                            );
-
-                return [
-                    $('<div>').addClass('datepicker-days')
-                        .append($('<table>').addClass('table-condensed')
-                            .append(headTemplate)
-                            .append($('<tbody>'))
-                            ),
-                    $('<div>').addClass('datepicker-months')
-                        .append($('<table>').addClass('table-condensed')
-                            .append(headTemplate.clone())
-                            .append(contTemplate.clone())
-                            ),
-                    $('<div>').addClass('datepicker-years')
-                        .append($('<table>').addClass('table-condensed')
-                            .append(headTemplate.clone())
-                            .append(contTemplate.clone())
-                            ),
-                    $('<div>').addClass('datepicker-decades')
-                        .append($('<table>').addClass('table-condensed')
-                            .append(headTemplate.clone())
-                            .append(contTemplate.clone())
-                            )
-                ];
-            },
-
-            getTimePickerMainTemplate = function () {
-                var topRow = $('<tr>'),
-                    middleRow = $('<tr>'),
-                    bottomRow = $('<tr>');
-
-                if (isEnabled('h')) {
-                    topRow.append($('<td>')
-                        .append($('<a>').attr({href: '#', tabindex: '-1', 'title':'Increment Hour'}).addClass('btn').attr('data-action', 'incrementHours')
-                            .append($('<span>').addClass(options.icons.up))));
-                    middleRow.append($('<td>')
-                        .append($('<span>').addClass('timepicker-hour').attr({'data-time-component':'hours', 'title':'Pick Hour'}).attr('data-action', 'showHours')));
-                    bottomRow.append($('<td>')
-                        .append($('<a>').attr({href: '#', tabindex: '-1', 'title':'Decrement Hour'}).addClass('btn').attr('data-action', 'decrementHours')
-                            .append($('<span>').addClass(options.icons.down))));
-                }
-                if (isEnabled('m')) {
-                    if (isEnabled('h')) {
-                        topRow.append($('<td>').addClass('separator'));
-                        middleRow.append($('<td>').addClass('separator').html(':'));
-                        bottomRow.append($('<td>').addClass('separator'));
-                    }
-                    topRow.append($('<td>')
-                        .append($('<a>').attr({href: '#', tabindex: '-1', 'title':'Increment Minute'}).addClass('btn').attr('data-action', 'incrementMinutes')
-                            .append($('<span>').addClass(options.icons.up))));
-                    middleRow.append($('<td>')
-                        .append($('<span>').addClass('timepicker-minute').attr({'data-time-component': 'minutes', 'title':'Pick Minute'}).attr('data-action', 'showMinutes')));
-                    bottomRow.append($('<td>')
-                        .append($('<a>').attr({href: '#', tabindex: '-1', 'title':'Decrement Minute'}).addClass('btn').attr('data-action', 'decrementMinutes')
-                            .append($('<span>').addClass(options.icons.down))));
-                }
-                if (isEnabled('s')) {
-                    if (isEnabled('m')) {
-                        topRow.append($('<td>').addClass('separator'));
-                        middleRow.append($('<td>').addClass('separator').html(':'));
-                        bottomRow.append($('<td>').addClass('separator'));
-                    }
-                    topRow.append($('<td>')
-                        .append($('<a>').attr({href: '#', tabindex: '-1', 'title':'Increment Second'}).addClass('btn').attr('data-action', 'incrementSeconds')
-                            .append($('<span>').addClass(options.icons.up))));
-                    middleRow.append($('<td>')
-                        .append($('<span>').addClass('timepicker-second').attr({'data-time-component': 'seconds', 'title':'Pick Second'}).attr('data-action', 'showSeconds')));
-                    bottomRow.append($('<td>')
-                        .append($('<a>').attr({href: '#', tabindex: '-1', 'title':'Decrement Second'}).addClass('btn').attr('data-action', 'decrementSeconds')
-                            .append($('<span>').addClass(options.icons.down))));
-                }
-
-                if (!use24Hours) {
-                    topRow.append($('<td>').addClass('separator'));
-                    middleRow.append($('<td>')
-                        .append($('<button>').addClass('btn btn-primary').attr({'data-action': 'togglePeriod', tabindex: '-1', 'title':'Toggle Period'})));
-                    bottomRow.append($('<td>').addClass('separator'));
-                }
-
-                return $('<div>').addClass('timepicker-picker')
-                    .append($('<table>').addClass('table-condensed')
-                        .append([topRow, middleRow, bottomRow]));
-            },
-
-            getTimePickerTemplate = function () {
-                var hoursView = $('<div>').addClass('timepicker-hours')
-                        .append($('<table>').addClass('table-condensed')),
-                    minutesView = $('<div>').addClass('timepicker-minutes')
-                        .append($('<table>').addClass('table-condensed')),
-                    secondsView = $('<div>').addClass('timepicker-seconds')
-                        .append($('<table>').addClass('table-condensed')),
-                    ret = [getTimePickerMainTemplate()];
-
-                if (isEnabled('h')) {
-                    ret.push(hoursView);
-                }
-                if (isEnabled('m')) {
-                    ret.push(minutesView);
-                }
-                if (isEnabled('s')) {
-                    ret.push(secondsView);
-                }
-
-                return ret;
-            },
-
-            getToolbar = function () {
-                var row = [];
-                if (options.showTodayButton) {
-                    row.push($('<td>').append($('<a>').attr({'data-action':'today', 'title':'Go to today'}).append($('<span>').addClass(options.icons.today))));
-                }
-                if (!options.sideBySide && hasDate() && hasTime()) {
-                    row.push($('<td>').append($('<a>').attr({'data-action':'togglePicker', 'title':'Select Time'}).append($('<span>').addClass(options.icons.time))));
-                }
-                if (options.showClear) {
-                    row.push($('<td>').append($('<a>').attr({'data-action':'clear', 'title':'Clear selection'}).append($('<span>').addClass(options.icons.clear))));
-                }
-                if (options.showClose) {
-                    row.push($('<td>').append($('<a>').attr({'data-action':'close', 'title':'Close the picker'}).append($('<span>').addClass(options.icons.close))));
-                }
-                return $('<table>').addClass('table-condensed').append($('<tbody>').append($('<tr>').append(row)));
-            },
-
-            getTemplate = function () {
-                var template = $('<div>').addClass('bootstrap-datetimepicker-widget dropdown-menu'),
-                    dateView = $('<div>').addClass('datepicker').append(getDatePickerTemplate()),
-                    timeView = $('<div>').addClass('timepicker').append(getTimePickerTemplate()),
-                    content = $('<ul>').addClass('list-unstyled'),
-                    toolbar = $('<li>').addClass('picker-switch' + (options.collapse ? ' accordion-toggle' : '')).append(getToolbar());
-
-                if (options.inline) {
-                    template.removeClass('dropdown-menu');
-                }
-
-                if (use24Hours) {
-                    template.addClass('usetwentyfour');
-                }
-                if (isEnabled('s') && !use24Hours) {
-                    template.addClass('wider');
-                }
-                if (options.sideBySide && hasDate() && hasTime()) {
-                    template.addClass('timepicker-sbs');
-                    template.append(
-                        $('<div>').addClass('row')
-                            .append(dateView.addClass('col-sm-6'))
-                            .append(timeView.addClass('col-sm-6'))
-                    );
-                    template.append(toolbar);
-                    return template;
-                }
-
-                if (options.toolbarPlacement === 'top') {
-                    content.append(toolbar);
-                }
-                if (hasDate()) {
-                    content.append($('<li>').addClass((options.collapse && hasTime() ? 'collapse in' : '')).append(dateView));
-                }
-                if (options.toolbarPlacement === 'default') {
-                    content.append(toolbar);
-                }
-                if (hasTime()) {
-                    content.append($('<li>').addClass((options.collapse && hasDate() ? 'collapse' : '')).append(timeView));
-                }
-                if (options.toolbarPlacement === 'bottom') {
-                    content.append(toolbar);
-                }
-                return template.append(content);
-            },
-
-            dataToOptions = function () {
-                var eData,
-                    dataOptions = {};
-
-                if (element.is('input') || options.inline) {
-                    eData = element.data();
-                } else {
-                    eData = element.find('input').data();
-                }
-
-                if (eData.dateOptions && eData.dateOptions instanceof Object) {
-                    dataOptions = $.extend(true, dataOptions, eData.dateOptions);
-                }
-
-                $.each(options, function (key) {
-                    var attributeName = 'date' + key.charAt(0).toUpperCase() + key.slice(1);
-                    if (eData[attributeName] !== undefined) {
-                        dataOptions[key] = eData[attributeName];
-                    }
-                });
-                return dataOptions;
-            },
-
-            place = function () {
-                var position = (component || element).position(),
-                    offset = (component || element).offset(),
-                    vertical = options.widgetPositioning.vertical,
-                    horizontal = options.widgetPositioning.horizontal,
-                    parent;
-
-                if (options.widgetParent) {
-                    parent = options.widgetParent.append(widget);
-                } else if (element.is('input')) {
-                    parent = element.after(widget).parent();
-                } else if (options.inline) {
-                    parent = element.append(widget);
-                    return;
-                } else {
-                    parent = element;
-                    element.children().first().after(widget);
-                }
-
-                // Top and bottom logic
-                if (vertical === 'auto') {
-                    if (offset.top + widget.height() * 1.5 >= $(window).height() + $(window).scrollTop() &&
-                        widget.height() + element.outerHeight() < offset.top) {
-                        vertical = 'top';
-                    } else {
-                        vertical = 'bottom';
-                    }
-                }
-
-                // Left and right logic
-                if (horizontal === 'auto') {
-                    if (parent.width() < offset.left + widget.outerWidth() / 2 &&
-                        offset.left + widget.outerWidth() > $(window).width()) {
-                        horizontal = 'right';
-                    } else {
-                        horizontal = 'left';
-                    }
-                }
-
-                if (vertical === 'top') {
-                    widget.addClass('top').removeClass('bottom');
-                } else {
-                    widget.addClass('bottom').removeClass('top');
-                }
-
-                if (horizontal === 'right') {
-                    widget.addClass('pull-right');
-                } else {
-                    widget.removeClass('pull-right');
-                }
-
-                // find the first parent element that has a relative css positioning
-                if (parent.css('position') !== 'relative') {
-                    parent = parent.parents().filter(function () {
-                        return $(this).css('position') === 'relative';
-                    }).first();
-                }
-
-                if (parent.length === 0) {
-                    throw new Error('datetimepicker component should be placed within a relative positioned container');
-                }
-
-                widget.css({
-                    top: vertical === 'top' ? 'auto' : position.top + element.outerHeight(),
-                    bottom: vertical === 'top' ? position.top + element.outerHeight() : 'auto',
-                    left: horizontal === 'left' ? (parent === element ? 0 : position.left) : 'auto',
-                    right: horizontal === 'left' ? 'auto' : parent.outerWidth() - element.outerWidth() - (parent === element ? 0 : position.left)
-                });
-            },
-
-            notifyEvent = function (e) {
-                if (e.type === 'dp.change' && ((e.date && e.date.isSame(e.oldDate)) || (!e.date && !e.oldDate))) {
-                    return;
-                }
-                element.trigger(e);
-            },
-
-            viewUpdate = function (e) {
-                if (e === 'y') {
-                    e = 'YYYY';
-                }
-                notifyEvent({
-                    type: 'dp.update',
-                    change: e,
-                    viewDate: viewDate.clone()
-                });
-            },
-
-            showMode = function (dir) {
-                if (!widget) {
-                    return;
-                }
-                if (dir) {
-                    currentViewMode = Math.max(minViewModeNumber, Math.min(3, currentViewMode + dir));
-                }
-                widget.find('.datepicker > div').hide().filter('.datepicker-' + datePickerModes[currentViewMode].clsName).show();
-            },
-
-            fillDow = function () {
-                var row = $('<tr>'),
-                    currentDate = viewDate.clone().startOf('w').startOf('d');
-
-                if (options.calendarWeeks === true) {
-                    row.append($('<th>').addClass('cw').text('#'));
-                }
-
-                while (currentDate.isBefore(viewDate.clone().endOf('w'))) {
-                    row.append($('<th>').addClass('dow').text(currentDate.format('dd')));
-                    currentDate.add(1, 'd');
-                }
-                widget.find('.datepicker-days thead').append(row);
-            },
-
-            isInDisabledDates = function (testDate) {
-                return options.disabledDates[testDate.format('YYYY-MM-DD')] === true;
-            },
-
-            isInEnabledDates = function (testDate) {
-                return options.enabledDates[testDate.format('YYYY-MM-DD')] === true;
-            },
-
-            isInDisabledHours = function (testDate) {
-                return options.disabledHours[testDate.format('H')] === true;
-            },
-
-            isInEnabledHours = function (testDate) {
-                return options.enabledHours[testDate.format('H')] === true;
-            },
-
-            isValid = function (targetMoment, granularity) {
-                if (!targetMoment.isValid()) {
-                    return false;
-                }
-                if (options.disabledDates && granularity === 'd' && isInDisabledDates(targetMoment)) {
-                    return false;
-                }
-                if (options.enabledDates && granularity === 'd' && !isInEnabledDates(targetMoment)) {
-                    return false;
-                }
-                if (options.minDate && targetMoment.isBefore(options.minDate, granularity)) {
-                    return false;
-                }
-                if (options.maxDate && targetMoment.isAfter(options.maxDate, granularity)) {
-                    return false;
-                }
-                if (options.daysOfWeekDisabled && granularity === 'd' && options.daysOfWeekDisabled.indexOf(targetMoment.day()) !== -1) {
-                    return false;
-                }
-                if (options.disabledHours && (granularity === 'h' || granularity === 'm' || granularity === 's') && isInDisabledHours(targetMoment)) {
-                    return false;
-                }
-                if (options.enabledHours && (granularity === 'h' || granularity === 'm' || granularity === 's') && !isInEnabledHours(targetMoment)) {
-                    return false;
-                }
-                if (options.disabledTimeIntervals && (granularity === 'h' || granularity === 'm' || granularity === 's')) {
-                    var found = false;
-                    $.each(options.disabledTimeIntervals, function () {
-                        if (targetMoment.isBetween(this[0], this[1])) {
-                            found = true;
-                            return false;
-                        }
-                    });
-                    if (found) {
-                        return false;
-                    }
-                }
-                return true;
-            },
-
-            fillMonths = function () {
-                var spans = [],
-                    monthsShort = viewDate.clone().startOf('y').startOf('d');
-                while (monthsShort.isSame(viewDate, 'y')) {
-                    spans.push($('<span>').attr('data-action', 'selectMonth').addClass('month').text(monthsShort.format('MMM')));
-                    monthsShort.add(1, 'M');
-                }
-                widget.find('.datepicker-months td').empty().append(spans);
-            },
-
-            updateMonths = function () {
-                var monthsView = widget.find('.datepicker-months'),
-                    monthsViewHeader = monthsView.find('th'),
-                    months = monthsView.find('tbody').find('span');
-
-                monthsViewHeader.eq(0).find('span').attr('title', 'Previous Year');
-                monthsViewHeader.eq(1).attr('title', 'Select Year');
-                monthsViewHeader.eq(2).find('span').attr('title', 'Next Year');
-
-                monthsView.find('.disabled').removeClass('disabled');
-
-                if (!isValid(viewDate.clone().subtract(1, 'y'), 'y')) {
-                    monthsViewHeader.eq(0).addClass('disabled');
-                }
-
-                monthsViewHeader.eq(1).text(viewDate.year());
-
-                if (!isValid(viewDate.clone().add(1, 'y'), 'y')) {
-                    monthsViewHeader.eq(2).addClass('disabled');
-                }
-
-                months.removeClass('active');
-                if (date.isSame(viewDate, 'y') && !unset) {
-                    months.eq(date.month()).addClass('active');
-                }
-
-                months.each(function (index) {
-                    if (!isValid(viewDate.clone().month(index), 'M')) {
-                        $(this).addClass('disabled');
-                    }
-                });
-            },
-
-            updateYears = function () {
-                var yearsView = widget.find('.datepicker-years'),
-                    yearsViewHeader = yearsView.find('th'),
-                    startYear = viewDate.clone().subtract(5, 'y'),
-                    endYear = viewDate.clone().add(6, 'y'),
-                    html = '';
-
-                yearsViewHeader.eq(0).find('span').attr('title', 'Previous Decade');
-                yearsViewHeader.eq(1).attr('title', 'Select Decade');
-                yearsViewHeader.eq(2).find('span').attr('title', 'Next Decade');
-
-                yearsView.find('.disabled').removeClass('disabled');
-
-                if (options.minDate && options.minDate.isAfter(startYear, 'y')) {
-                    yearsViewHeader.eq(0).addClass('disabled');
-                }
-
-                yearsViewHeader.eq(1).text(startYear.year() + '-' + endYear.year());
-
-                if (options.maxDate && options.maxDate.isBefore(endYear, 'y')) {
-                    yearsViewHeader.eq(2).addClass('disabled');
-                }
-
-                while (!startYear.isAfter(endYear, 'y')) {
-                    html += '<span data-action="selectYear" class="year' + (startYear.isSame(date, 'y') && !unset ? ' active' : '') + (!isValid(startYear, 'y') ? ' disabled' : '') + '">' + startYear.year() + '</span>';
-                    startYear.add(1, 'y');
-                }
-
-                yearsView.find('td').html(html);
-            },
-
-            updateDecades = function () {
-                var decadesView = widget.find('.datepicker-decades'),
-                    decadesViewHeader = decadesView.find('th'),
-                    startDecade = viewDate.isBefore(moment({y: 1999})) ? moment({y: 1899}) : moment({y: 1999}),
-                    endDecade = startDecade.clone().add(100, 'y'),
-                    html = '';
-
-                decadesViewHeader.eq(0).find('span').attr('title', 'Previous Century');
-                decadesViewHeader.eq(2).find('span').attr('title', 'Next Century');
-
-                decadesView.find('.disabled').removeClass('disabled');
-
-                if (startDecade.isSame(moment({y: 1900})) || (options.minDate && options.minDate.isAfter(startDecade, 'y'))) {
-                    decadesViewHeader.eq(0).addClass('disabled');
-                }
-
-                decadesViewHeader.eq(1).text(startDecade.year() + '-' + endDecade.year());
-
-                if (startDecade.isSame(moment({y: 2000})) || (options.maxDate && options.maxDate.isBefore(endDecade, 'y'))) {
-                    decadesViewHeader.eq(2).addClass('disabled');
-                }
-
-                while (!startDecade.isAfter(endDecade, 'y')) {
-                    html += '<span data-action="selectDecade" class="decade' + (startDecade.isSame(date, 'y') ? ' active' : '') +
-                        (!isValid(startDecade, 'y') ? ' disabled' : '') + '" data-selection="' + (startDecade.year() + 6) + '">' + (startDecade.year() + 1) + ' - ' + (startDecade.year() + 12) + '</span>';
-                    startDecade.add(12, 'y');
-                }
-                html += '<span></span><span></span><span></span>'; //push the dangling block over, at least this way it's even
-
-                decadesView.find('td').html(html);
-            },
-
-            fillDate = function () {
-                var daysView = widget.find('.datepicker-days'),
-                    daysViewHeader = daysView.find('th'),
-                    currentDate,
-                    html = [],
-                    row,
-                    clsName,
-                    i;
-
-                if (!hasDate()) {
-                    return;
-                }
-
-                daysViewHeader.eq(0).find('span').attr('title', 'Previous Month');
-                daysViewHeader.eq(1).attr('title', 'Select Month');
-                daysViewHeader.eq(2).find('span').attr('title', 'Next Month');
-
-                daysView.find('.disabled').removeClass('disabled');
-                daysViewHeader.eq(1).text(viewDate.format(options.dayViewHeaderFormat));
-
-                if (!isValid(viewDate.clone().subtract(1, 'M'), 'M')) {
-                    daysViewHeader.eq(0).addClass('disabled');
-                }
-                if (!isValid(viewDate.clone().add(1, 'M'), 'M')) {
-                    daysViewHeader.eq(2).addClass('disabled');
-                }
-
-                currentDate = viewDate.clone().startOf('M').startOf('w').startOf('d');
-
-                for (i = 0; i < 42; i++) { //always display 42 days (should show 6 weeks)
-                    if (currentDate.weekday() === 0) {
-                        row = $('<tr>');
-                        if (options.calendarWeeks) {
-                            row.append('<td class="cw">' + currentDate.week() + '</td>');
-                        }
-                        html.push(row);
-                    }
-                    clsName = '';
-                    if (currentDate.isBefore(viewDate, 'M')) {
-                        clsName += ' old';
-                    }
-                    if (currentDate.isAfter(viewDate, 'M')) {
-                        clsName += ' new';
-                    }
-                    if (currentDate.isSame(date, 'd') && !unset) {
-                        clsName += ' active';
-                    }
-                    if (!isValid(currentDate, 'd')) {
-                        clsName += ' disabled';
-                    }
-                    if (currentDate.isSame(moment(), 'd')) {
-                        clsName += ' today';
-                    }
-                    if (currentDate.day() === 0 || currentDate.day() === 6) {
-                        clsName += ' weekend';
-                    }
-                    row.append('<td data-action="selectDay" data-day="' + currentDate.format('L') + '" class="day' + clsName + '">' + currentDate.date() + '</td>');
-                    currentDate.add(1, 'd');
-                }
-
-                daysView.find('tbody').empty().append(html);
-
-                updateMonths();
-
-                updateYears();
-
-                updateDecades();
-            },
-
-            fillHours = function () {
-                var table = widget.find('.timepicker-hours table'),
-                    currentHour = viewDate.clone().startOf('d'),
-                    html = [],
-                    row = $('<tr>');
-
-                if (viewDate.hour() > 11 && !use24Hours) {
-                    currentHour.hour(12);
-                }
-                while (currentHour.isSame(viewDate, 'd') && (use24Hours || (viewDate.hour() < 12 && currentHour.hour() < 12) || viewDate.hour() > 11)) {
-                    if (currentHour.hour() % 4 === 0) {
-                        row = $('<tr>');
-                        html.push(row);
-                    }
-                    row.append('<td data-action="selectHour" class="hour' + (!isValid(currentHour, 'h') ? ' disabled' : '') + '">' + currentHour.format(use24Hours ? 'HH' : 'hh') + '</td>');
-                    currentHour.add(1, 'h');
-                }
-                table.empty().append(html);
-            },
-
-            fillMinutes = function () {
-                var table = widget.find('.timepicker-minutes table'),
-                    currentMinute = viewDate.clone().startOf('h'),
-                    html = [],
-                    row = $('<tr>'),
-                    step = options.stepping === 1 ? 5 : options.stepping;
-
-                while (viewDate.isSame(currentMinute, 'h')) {
-                    if (currentMinute.minute() % (step * 4) === 0) {
-                        row = $('<tr>');
-                        html.push(row);
-                    }
-                    row.append('<td data-action="selectMinute" class="minute' + (!isValid(currentMinute, 'm') ? ' disabled' : '') + '">' + currentMinute.format('mm') + '</td>');
-                    currentMinute.add(step, 'm');
-                }
-                table.empty().append(html);
-            },
-
-            fillSeconds = function () {
-                var table = widget.find('.timepicker-seconds table'),
-                    currentSecond = viewDate.clone().startOf('m'),
-                    html = [],
-                    row = $('<tr>');
-
-                while (viewDate.isSame(currentSecond, 'm')) {
-                    if (currentSecond.second() % 20 === 0) {
-                        row = $('<tr>');
-                        html.push(row);
-                    }
-                    row.append('<td data-action="selectSecond" class="second' + (!isValid(currentSecond, 's') ? ' disabled' : '') + '">' + currentSecond.format('ss') + '</td>');
-                    currentSecond.add(5, 's');
-                }
-
-                table.empty().append(html);
-            },
-
-            fillTime = function () {
-                var toggle, newDate, timeComponents = widget.find('.timepicker span[data-time-component]');
-
-                if (!use24Hours) {
-                    toggle = widget.find('.timepicker [data-action=togglePeriod]');
-                    newDate = date.clone().add((date.hours() >= 12) ? -12 : 12, 'h');
-
-                    toggle.text(date.format('A'));
-
-                    if (isValid(newDate, 'h')) {
-                        toggle.removeClass('disabled');
-                    } else {
-                        toggle.addClass('disabled');
-                    }
-                }
-                timeComponents.filter('[data-time-component=hours]').text(date.format(use24Hours ? 'HH' : 'hh'));
-                timeComponents.filter('[data-time-component=minutes]').text(date.format('mm'));
-                timeComponents.filter('[data-time-component=seconds]').text(date.format('ss'));
-
-                fillHours();
-                fillMinutes();
-                fillSeconds();
-            },
-
-            update = function () {
-                if (!widget) {
-                    return;
-                }
-                fillDate();
-                fillTime();
-            },
-
-            setValue = function (targetMoment) {
-                var oldDate = unset ? null : date;
-
-                // case of calling setValue(null or false)
-                if (!targetMoment) {
-                    unset = true;
-                    input.val('');
-                    element.data('date', '');
-                    notifyEvent({
-                        type: 'dp.change',
-                        date: false,
-                        oldDate: oldDate
-                    });
-                    update();
-                    return;
-                }
-
-                targetMoment = targetMoment.clone().locale(options.locale);
-
-                if (options.stepping !== 1) {
-                    targetMoment.minutes((Math.round(targetMoment.minutes() / options.stepping) * options.stepping) % 60).seconds(0);
-                }
-
-                if (isValid(targetMoment)) {
-                    date = targetMoment;
-                    viewDate = date.clone();
-                    input.val(date.format(actualFormat));
-                    element.data('date', date.format(actualFormat));
-                    unset = false;
-                    update();
-                    notifyEvent({
-                        type: 'dp.change',
-                        date: date.clone(),
-                        oldDate: oldDate
-                    });
-                } else {
-                    if (!options.keepInvalid) {
-                        input.val(unset ? '' : date.format(actualFormat));
-                    }
-                    notifyEvent({
-                        type: 'dp.error',
-                        date: targetMoment
-                    });
-                }
-            },
-
-            hide = function () {
-                ///<summary>Hides the widget. Possibly will emit dp.hide</summary>
-                var transitioning = false;
-                if (!widget) {
-                    return picker;
-                }
-                // Ignore event if in the middle of a picker transition
-                widget.find('.collapse').each(function () {
-                    var collapseData = $(this).data('collapse');
-                    if (collapseData && collapseData.transitioning) {
-                        transitioning = true;
-                        return false;
-                    }
-                    return true;
-                });
-                if (transitioning) {
-                    return picker;
-                }
-                if (component && component.hasClass('btn')) {
-                    component.toggleClass('active');
-                }
-                widget.hide();
-
-                $(window).off('resize', place);
-                widget.off('click', '[data-action]');
-                widget.off('mousedown', false);
-
-                widget.remove();
-                widget = false;
-
-                notifyEvent({
-                    type: 'dp.hide',
-                    date: date.clone()
-                });
-                return picker;
-            },
-
-            clear = function () {
-                setValue(null);
-            },
-
-            /********************************************************************************
-             *
-             * Widget UI interaction functions
-             *
-             ********************************************************************************/
-            actions = {
-                next: function () {
-                    var navFnc = datePickerModes[currentViewMode].navFnc;
-                    viewDate.add(datePickerModes[currentViewMode].navStep, navFnc);
-                    fillDate();
-                    viewUpdate(navFnc);
-                },
-
-                previous: function () {
-                    var navFnc = datePickerModes[currentViewMode].navFnc;
-                    viewDate.subtract(datePickerModes[currentViewMode].navStep, navFnc);
-                    fillDate();
-                    viewUpdate(navFnc);
-                },
-
-                pickerSwitch: function () {
-                    showMode(1);
-                },
-
-                selectMonth: function (e) {
-                    var month = $(e.target).closest('tbody').find('span').index($(e.target));
-                    viewDate.month(month);
-                    if (currentViewMode === minViewModeNumber) {
-                        setValue(date.clone().year(viewDate.year()).month(viewDate.month()));
-                        if (!options.inline) {
-                            hide();
-                        }
-                    } else {
-                        showMode(-1);
-                        fillDate();
-                    }
-                    viewUpdate('M');
-                },
-
-                selectYear: function (e) {
-                    var year = parseInt($(e.target).text(), 10) || 0;
-                    viewDate.year(year);
-                    if (currentViewMode === minViewModeNumber) {
-                        setValue(date.clone().year(viewDate.year()));
-                        if (!options.inline) {
-                            hide();
-                        }
-                    } else {
-                        showMode(-1);
-                        fillDate();
-                    }
-                    viewUpdate('YYYY');
-                },
-
-                selectDecade: function (e) {
-                    var year = parseInt($(e.target).data('selection'), 10) || 0;
-                    viewDate.year(year);
-                    if (currentViewMode === minViewModeNumber) {
-                        setValue(date.clone().year(viewDate.year()));
-                        if (!options.inline) {
-                            hide();
-                        }
-                    } else {
-                        showMode(-1);
-                        fillDate();
-                    }
-                    viewUpdate('YYYY');
-                },
-
-                selectDay: function (e) {
-                    var day = viewDate.clone();
-                    if ($(e.target).is('.old')) {
-                        day.subtract(1, 'M');
-                    }
-                    if ($(e.target).is('.new')) {
-                        day.add(1, 'M');
-                    }
-                    setValue(day.date(parseInt($(e.target).text(), 10)));
-                    if (!hasTime() && !options.keepOpen && !options.inline) {
-                        hide();
-                    }
-                },
-
-                incrementHours: function () {
-                    var newDate = date.clone().add(1, 'h');
-                    if (isValid(newDate, 'h')) {
-                        setValue(newDate);
-                    }
-                },
-
-                incrementMinutes: function () {
-                    var newDate = date.clone().add(options.stepping, 'm');
-                    if (isValid(newDate, 'm')) {
-                        setValue(newDate);
-                    }
-                },
-
-                incrementSeconds: function () {
-                    var newDate = date.clone().add(1, 's');
-                    if (isValid(newDate, 's')) {
-                        setValue(newDate);
-                    }
-                },
-
-                decrementHours: function () {
-                    var newDate = date.clone().subtract(1, 'h');
-                    if (isValid(newDate, 'h')) {
-                        setValue(newDate);
-                    }
-                },
-
-                decrementMinutes: function () {
-                    var newDate = date.clone().subtract(options.stepping, 'm');
-                    if (isValid(newDate, 'm')) {
-                        setValue(newDate);
-                    }
-                },
-
-                decrementSeconds: function () {
-                    var newDate = date.clone().subtract(1, 's');
-                    if (isValid(newDate, 's')) {
-                        setValue(newDate);
-                    }
-                },
-
-                togglePeriod: function () {
-                    setValue(date.clone().add((date.hours() >= 12) ? -12 : 12, 'h'));
-                },
-
-                togglePicker: function (e) {
-                    var $this = $(e.target),
-                        $parent = $this.closest('ul'),
-                        expanded = $parent.find('.in'),
-                        closed = $parent.find('.collapse:not(.in)'),
-                        collapseData;
-
-                    if (expanded && expanded.length) {
-                        collapseData = expanded.data('collapse');
-                        if (collapseData && collapseData.transitioning) {
-                            return;
-                        }
-                        if (expanded.collapse) { // if collapse plugin is available through bootstrap.js then use it
-                            expanded.collapse('hide');
-                            closed.collapse('show');
-                        } else { // otherwise just toggle in class on the two views
-                            expanded.removeClass('in');
-                            closed.addClass('in');
-                        }
-                        if ($this.is('span')) {
-                            $this.toggleClass(options.icons.time + ' ' + options.icons.date);
-                        } else {
-                            $this.find('span').toggleClass(options.icons.time + ' ' + options.icons.date);
-                        }
-
-                        // NOTE: uncomment if toggled state will be restored in show()
-                        //if (component) {
-                        //    component.find('span').toggleClass(options.icons.time + ' ' + options.icons.date);
-                        //}
-                    }
-                },
-
-                showPicker: function () {
-                    widget.find('.timepicker > div:not(.timepicker-picker)').hide();
-                    widget.find('.timepicker .timepicker-picker').show();
-                },
-
-                showHours: function () {
-                    widget.find('.timepicker .timepicker-picker').hide();
-                    widget.find('.timepicker .timepicker-hours').show();
-                },
-
-                showMinutes: function () {
-                    widget.find('.timepicker .timepicker-picker').hide();
-                    widget.find('.timepicker .timepicker-minutes').show();
-                },
-
-                showSeconds: function () {
-                    widget.find('.timepicker .timepicker-picker').hide();
-                    widget.find('.timepicker .timepicker-seconds').show();
-                },
-
-                selectHour: function (e) {
-                    var hour = parseInt($(e.target).text(), 10);
-
-                    if (!use24Hours) {
-                        if (date.hours() >= 12) {
-                            if (hour !== 12) {
-                                hour += 12;
-                            }
-                        } else {
-                            if (hour === 12) {
-                                hour = 0;
-                            }
-                        }
-                    }
-                    setValue(date.clone().hours(hour));
-                    actions.showPicker.call(picker);
-                },
-
-                selectMinute: function (e) {
-                    setValue(date.clone().minutes(parseInt($(e.target).text(), 10)));
-                    actions.showPicker.call(picker);
-                },
-
-                selectSecond: function (e) {
-                    setValue(date.clone().seconds(parseInt($(e.target).text(), 10)));
-                    actions.showPicker.call(picker);
-                },
-
-                clear: clear,
-
-                today: function () {
-                    if (isValid(moment(), 'd')) {
-                        setValue(moment());
-                    }
-                },
-
-                close: hide
-            },
-
-            doAction = function (e) {
-                if ($(e.currentTarget).is('.disabled')) {
-                    return false;
-                }
-                actions[$(e.currentTarget).data('action')].apply(picker, arguments);
-                return false;
-            },
-
-            show = function () {
-                ///<summary>Shows the widget. Possibly will emit dp.show and dp.change</summary>
-                var currentMoment,
-                    useCurrentGranularity = {
-                        'year': function (m) {
-                            return m.month(0).date(1).hours(0).seconds(0).minutes(0);
-                        },
-                        'month': function (m) {
-                            return m.date(1).hours(0).seconds(0).minutes(0);
-                        },
-                        'day': function (m) {
-                            return m.hours(0).seconds(0).minutes(0);
-                        },
-                        'hour': function (m) {
-                            return m.seconds(0).minutes(0);
-                        },
-                        'minute': function (m) {
-                            return m.seconds(0);
-                        }
-                    };
-
-                if (input.prop('disabled') || (!options.ignoreReadonly && input.prop('readonly')) || widget) {
-                    return picker;
-                }
-                if (input.val() !== undefined && input.val().trim().length !== 0) {
-                    setValue(parseInputDate(input.val().trim()));
-                } else if (options.useCurrent && unset && ((input.is('input') && input.val().trim().length === 0) || options.inline)) {
-                    currentMoment = moment();
-                    if (typeof options.useCurrent === 'string') {
-                        currentMoment = useCurrentGranularity[options.useCurrent](currentMoment);
-                    }
-                    setValue(currentMoment);
-                }
-
-                widget = getTemplate();
-
-                fillDow();
-                fillMonths();
-
-                widget.find('.timepicker-hours').hide();
-                widget.find('.timepicker-minutes').hide();
-                widget.find('.timepicker-seconds').hide();
-
-                update();
-                showMode();
-
-                $(window).on('resize', place);
-                widget.on('click', '[data-action]', doAction); // this handles clicks on the widget
-                widget.on('mousedown', false);
-
-                if (component && component.hasClass('btn')) {
-                    component.toggleClass('active');
-                }
-                widget.show();
-                place();
-
-                if (options.focusOnShow && !input.is(':focus')) {
-                    input.focus();
-                }
-
-                notifyEvent({
-                    type: 'dp.show'
-                });
-                return picker;
-            },
-
-            toggle = function () {
-                /// <summary>Shows or hides the widget</summary>
-                return (widget ? hide() : show());
-            },
-
-            parseInputDate = function (inputDate) {
-                if (options.parseInputDate === undefined) {
-                    if (moment.isMoment(inputDate) || inputDate instanceof Date) {
-                        inputDate = moment(inputDate);
-                    } else {
-                        inputDate = moment(inputDate, parseFormats, options.useStrict);
-                    }
-                } else {
-                    inputDate = options.parseInputDate(inputDate);
-                }
-                inputDate.locale(options.locale);
-                return inputDate;
-            },
-
-            keydown = function (e) {
-                var handler = null,
-                    index,
-                    index2,
-                    pressedKeys = [],
-                    pressedModifiers = {},
-                    currentKey = e.which,
-                    keyBindKeys,
-                    allModifiersPressed,
-                    pressed = 'p';
-
-                keyState[currentKey] = pressed;
-
-                for (index in keyState) {
-                    if (keyState.hasOwnProperty(index) && keyState[index] === pressed) {
-                        pressedKeys.push(index);
-                        if (parseInt(index, 10) !== currentKey) {
-                            pressedModifiers[index] = true;
-                        }
-                    }
-                }
-
-                for (index in options.keyBinds) {
-                    if (options.keyBinds.hasOwnProperty(index) && typeof (options.keyBinds[index]) === 'function') {
-                        keyBindKeys = index.split(' ');
-                        if (keyBindKeys.length === pressedKeys.length && keyMap[currentKey] === keyBindKeys[keyBindKeys.length - 1]) {
-                            allModifiersPressed = true;
-                            for (index2 = keyBindKeys.length - 2; index2 >= 0; index2--) {
-                                if (!(keyMap[keyBindKeys[index2]] in pressedModifiers)) {
-                                    allModifiersPressed = false;
-                                    break;
-                                }
-                            }
-                            if (allModifiersPressed) {
-                                handler = options.keyBinds[index];
-                                break;
-                            }
-                        }
-                    }
-                }
-
-                if (handler) {
-                    handler.call(picker, widget);
-                    e.stopPropagation();
-                    e.preventDefault();
-                }
-            },
-
-            keyup = function (e) {
-                keyState[e.which] = 'r';
-                e.stopPropagation();
-                e.preventDefault();
-            },
-
-            change = function (e) {
-                var val = $(e.target).val().trim(),
-                    parsedDate = val ? parseInputDate(val) : null;
-                setValue(parsedDate);
-                e.stopImmediatePropagation();
-                return false;
-            },
-
-            attachDatePickerElementEvents = function () {
-                input.on({
-                    'change': change,
-                    'blur': options.debug ? '' : hide,
-                    'keydown': keydown,
-                    'keyup': keyup,
-                    'focus': options.allowInputToggle ? show : ''
-                });
-
-                if (element.is('input')) {
-                    input.on({
-                        'focus': show
-                    });
-                } else if (component) {
-                    component.on('click', toggle);
-                    component.on('mousedown', false);
-                }
-            },
-
-            detachDatePickerElementEvents = function () {
-                input.off({
-                    'change': change,
-                    'blur': hide,
-                    'keydown': keydown,
-                    'keyup': keyup,
-                    'focus': options.allowInputToggle ? hide : ''
-                });
-
-                if (element.is('input')) {
-                    input.off({
-                        'focus': show
-                    });
-                } else if (component) {
-                    component.off('click', toggle);
-                    component.off('mousedown', false);
-                }
-            },
-
-            indexGivenDates = function (givenDatesArray) {
-                // Store given enabledDates and disabledDates as keys.
-                // This way we can check their existence in O(1) time instead of looping through whole array.
-                // (for example: options.enabledDates['2014-02-27'] === true)
-                var givenDatesIndexed = {};
-                $.each(givenDatesArray, function () {
-                    var dDate = parseInputDate(this);
-                    if (dDate.isValid()) {
-                        givenDatesIndexed[dDate.format('YYYY-MM-DD')] = true;
-                    }
-                });
-                return (Object.keys(givenDatesIndexed).length) ? givenDatesIndexed : false;
-            },
-
-            indexGivenHours = function (givenHoursArray) {
-                // Store given enabledHours and disabledHours as keys.
-                // This way we can check their existence in O(1) time instead of looping through whole array.
-                // (for example: options.enabledHours['2014-02-27'] === true)
-                var givenHoursIndexed = {};
-                $.each(givenHoursArray, function () {
-                    givenHoursIndexed[this] = true;
-                });
-                return (Object.keys(givenHoursIndexed).length) ? givenHoursIndexed : false;
-            },
-
-            initFormatting = function () {
-                var format = options.format || 'L LT';
-
-                actualFormat = format.replace(/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g, function (formatInput) {
-                    var newinput = date.localeData().longDateFormat(formatInput) || formatInput;
-                    return newinput.replace(/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g, function (formatInput2) { //temp fix for #740
-                        return date.localeData().longDateFormat(formatInput2) || formatInput2;
-                    });
-                });
-
-
-                parseFormats = options.extraFormats ? options.extraFormats.slice() : [];
-                if (parseFormats.indexOf(format) < 0 && parseFormats.indexOf(actualFormat) < 0) {
-                    parseFormats.push(actualFormat);
-                }
-
-                use24Hours = (actualFormat.toLowerCase().indexOf('a') < 1 && actualFormat.replace(/\[.*?\]/g, '').indexOf('h') < 1);
-
-                if (isEnabled('y')) {
-                    minViewModeNumber = 2;
-                }
-                if (isEnabled('M')) {
-                    minViewModeNumber = 1;
-                }
-                if (isEnabled('d')) {
-                    minViewModeNumber = 0;
-                }
-
-                currentViewMode = Math.max(minViewModeNumber, currentViewMode);
-
-                if (!unset) {
-                    setValue(date);
-                }
-            };
-
-        /********************************************************************************
-         *
-         * Public API functions
-         * =====================
-         *
-         * Important: Do not expose direct references to private objects or the options
-         * object to the outer world. Always return a clone when returning values or make
-         * a clone when setting a private variable.
-         *
-         ********************************************************************************/
-        picker.destroy = function () {
-            ///<summary>Destroys the widget and removes all attached event listeners</summary>
-            hide();
-            detachDatePickerElementEvents();
-            element.removeData('DateTimePicker');
-            element.removeData('date');
-        };
-
-        picker.toggle = toggle;
-
-        picker.show = show;
-
-        picker.hide = hide;
-
-        picker.disable = function () {
-            ///<summary>Disables the input element, the component is attached to, by adding a disabled="true" attribute to it.
-            ///If the widget was visible before that call it is hidden. Possibly emits dp.hide</summary>
-            hide();
-            if (component && component.hasClass('btn')) {
-                component.addClass('disabled');
-            }
-            input.prop('disabled', true);
-            return picker;
-        };
-
-        picker.enable = function () {
-            ///<summary>Enables the input element, the component is attached to, by removing disabled attribute from it.</summary>
-            if (component && component.hasClass('btn')) {
-                component.removeClass('disabled');
-            }
-            input.prop('disabled', false);
-            return picker;
-        };
-
-        picker.ignoreReadonly = function (ignoreReadonly) {
-            if (arguments.length === 0) {
-                return options.ignoreReadonly;
-            }
-            if (typeof ignoreReadonly !== 'boolean') {
-                throw new TypeError('ignoreReadonly () expects a boolean parameter');
-            }
-            options.ignoreReadonly = ignoreReadonly;
-            return picker;
-        };
-
-        picker.options = function (newOptions) {
-            if (arguments.length === 0) {
-                return $.extend(true, {}, options);
-            }
-
-            if (!(newOptions instanceof Object)) {
-                throw new TypeError('options() options parameter should be an object');
-            }
-            $.extend(true, options, newOptions);
-            $.each(options, function (key, value) {
-                if (picker[key] !== undefined) {
-                    picker[key](value);
-                } else {
-                    throw new TypeError('option ' + key + ' is not recognized!');
-                }
-            });
-            return picker;
-        };
-
-        picker.date = function (newDate) {
-            ///<signature helpKeyword="$.fn.datetimepicker.date">
-            ///<summary>Returns the component's model current date, a moment object or null if not set.</summary>
-            ///<returns type="Moment">date.clone()</returns>
-            ///</signature>
-            ///<signature>
-            ///<summary>Sets the components model current moment to it. Passing a null value unsets the components model current moment. Parsing of the newDate parameter is made using moment library with the options.format and options.useStrict components configuration.</summary>
-            ///<param name="newDate" locid="$.fn.datetimepicker.date_p:newDate">Takes string, Date, moment, null parameter.</param>
-            ///</signature>
-            if (arguments.length === 0) {
-                if (unset) {
-                    return null;
-                }
-                return date.clone();
-            }
-
-            if (newDate !== null && typeof newDate !== 'string' && !moment.isMoment(newDate) && !(newDate instanceof Date)) {
-                throw new TypeError('date() parameter must be one of [null, string, moment or Date]');
-            }
-
-            setValue(newDate === null ? null : parseInputDate(newDate));
-            return picker;
-        };
-
-        picker.format = function (newFormat) {
-            ///<summary>test su</summary>
-            ///<param name="newFormat">info about para</param>
-            ///<returns type="string|boolean">returns foo</returns>
-            if (arguments.length === 0) {
-                return options.format;
-            }
-
-            if ((typeof newFormat !== 'string') && ((typeof newFormat !== 'boolean') || (newFormat !== false))) {
-                throw new TypeError('format() expects a sting or boolean:false parameter ' + newFormat);
-            }
-
-            options.format = newFormat;
-            if (actualFormat) {
-                initFormatting(); // reinit formatting
-            }
-            return picker;
-        };
-
-        picker.dayViewHeaderFormat = function (newFormat) {
-            if (arguments.length === 0) {
-                return options.dayViewHeaderFormat;
-            }
-
-            if (typeof newFormat !== 'string') {
-                throw new TypeError('dayViewHeaderFormat() expects a string parameter');
-            }
-
-            options.dayViewHeaderFormat = newFormat;
-            return picker;
-        };
-
-        picker.extraFormats = function (formats) {
-            if (arguments.length === 0) {
-                return options.extraFormats;
-            }
-
-            if (formats !== false && !(formats instanceof Array)) {
-                throw new TypeError('extraFormats() expects an array or false parameter');
-            }
-
-            options.extraFormats = formats;
-            if (parseFormats) {
-                initFormatting(); // reinit formatting
-            }
-            return picker;
-        };
-
-        picker.disabledDates = function (dates) {
-            ///<signature helpKeyword="$.fn.datetimepicker.disabledDates">
-            ///<summary>Returns an array with the currently set disabled dates on the component.</summary>
-            ///<returns type="array">options.disabledDates</returns>
-            ///</signature>
-            ///<signature>
-            ///<summary>Setting this takes precedence over options.minDate, options.maxDate configuration. Also calling this function removes the configuration of
-            ///options.enabledDates if such exist.</summary>
-            ///<param name="dates" locid="$.fn.datetimepicker.disabledDates_p:dates">Takes an [ string or Date or moment ] of values and allows the user to select only from those days.</param>
-            ///</signature>
-            if (arguments.length === 0) {
-                return (options.disabledDates ? $.extend({}, options.disabledDates) : options.disabledDates);
-            }
-
-            if (!dates) {
-                options.disabledDates = false;
-                update();
-                return picker;
-            }
-            if (!(dates instanceof Array)) {
-                throw new TypeError('disabledDates() expects an array parameter');
-            }
-            options.disabledDates = indexGivenDates(dates);
-            options.enabledDates = false;
-            update();
-            return picker;
-        };
-
-        picker.enabledDates = function (dates) {
-            ///<signature helpKeyword="$.fn.datetimepicker.enabledDates">
-            ///<summary>Returns an array with the currently set enabled dates on the component.</summary>
-            ///<returns type="array">options.enabledDates</returns>
-            ///</signature>
-            ///<signature>
-            ///<summary>Setting this takes precedence over options.minDate, options.maxDate configuration. Also calling this function removes the configuration of options.disabledDates if such exist.</summary>
-            ///<param name="dates" locid="$.fn.datetimepicker.enabledDates_p:dates">Takes an [ string or Date or moment ] of values and allows the user to select only from those days.</param>
-            ///</signature>
-            if (arguments.length === 0) {
-                return (options.enabledDates ? $.extend({}, options.enabledDates) : options.enabledDates);
-            }
-
-            if (!dates) {
-                options.enabledDates = false;
-                update();
-                return picker;
-            }
-            if (!(dates instanceof Array)) {
-                throw new TypeError('enabledDates() expects an array parameter');
-            }
-            options.enabledDates = indexGivenDates(dates);
-            options.disabledDates = false;
-            update();
-            return picker;
-        };
-
-        picker.daysOfWeekDisabled = function (daysOfWeekDisabled) {
-            if (arguments.length === 0) {
-                return options.daysOfWeekDisabled.splice(0);
-            }
-
-            if ((typeof daysOfWeekDisabled === 'boolean') && !daysOfWeekDisabled) {
-                options.daysOfWeekDisabled = false;
-                update();
-                return picker;
-            }
-
-            if (!(daysOfWeekDisabled instanceof Array)) {
-                throw new TypeError('daysOfWeekDisabled() expects an array parameter');
-            }
-            options.daysOfWeekDisabled = daysOfWeekDisabled.reduce(function (previousValue, currentValue) {
-                currentValue = parseInt(currentValue, 10);
-                if (currentValue > 6 || currentValue < 0 || isNaN(currentValue)) {
-                    return previousValue;
-                }
-                if (previousValue.indexOf(currentValue) === -1) {
-                    previousValue.push(currentValue);
-                }
-                return previousValue;
-            }, []).sort();
-            if (options.useCurrent && !options.keepInvalid) {
-                var tries = 0;
-                while (!isValid(date, 'd')) {
-                    date.add(1, 'd');
-                    if (tries === 7) {
-                        throw 'Tried 7 times to find a valid date';
-                    }
-                    tries++;
-                }
-                setValue(date);
-            }
-            update();
-            return picker;
-        };
-
-        picker.maxDate = function (maxDate) {
-            if (arguments.length === 0) {
-                return options.maxDate ? options.maxDate.clone() : options.maxDate;
-            }
-
-            if ((typeof maxDate === 'boolean') && maxDate === false) {
-                options.maxDate = false;
-                update();
-                return picker;
-            }
-
-            if (typeof maxDate === 'string') {
-                if (maxDate === 'now' || maxDate === 'moment') {
-                    maxDate = moment();
-                }
-            }
-
-            var parsedDate = parseInputDate(maxDate);
-
-            if (!parsedDate.isValid()) {
-                throw new TypeError('maxDate() Could not parse date parameter: ' + maxDate);
-            }
-            if (options.minDate && parsedDate.isBefore(options.minDate)) {
-                throw new TypeError('maxDate() date parameter is before options.minDate: ' + parsedDate.format(actualFormat));
-            }
-            options.maxDate = parsedDate;
-            if (options.useCurrent && !options.keepInvalid && date.isAfter(maxDate)) {
-                setValue(options.maxDate);
-            }
-            if (viewDate.isAfter(parsedDate)) {
-                viewDate = parsedDate.clone();
-            }
-            update();
-            return picker;
-        };
-
-        picker.minDate = function (minDate) {
-            if (arguments.length === 0) {
-                return options.minDate ? options.minDate.clone() : options.minDate;
-            }
-
-            if ((typeof minDate === 'boolean') && minDate === false) {
-                options.minDate = false;
-                update();
-                return picker;
-            }
-
-            if (typeof minDate === 'string') {
-                if (minDate === 'now' || minDate === 'moment') {
-                    minDate = moment();
-                }
-            }
-
-            var parsedDate = parseInputDate(minDate);
-
-            if (!parsedDate.isValid()) {
-                throw new TypeError('minDate() Could not parse date parameter: ' + minDate);
-            }
-            if (options.maxDate && parsedDate.isAfter(options.maxDate)) {
-                throw new TypeError('minDate() date parameter is after options.maxDate: ' + parsedDate.format(actualFormat));
-            }
-            options.minDate = parsedDate;
-            if (options.useCurrent && !options.keepInvalid && date.isBefore(minDate)) {
-                setValue(options.minDate);
-            }
-            if (viewDate.isBefore(parsedDate)) {
-                viewDate = parsedDate.clone();
-            }
-            update();
-            return picker;
-        };
-
-        picker.defaultDate = function (defaultDate) {
-            ///<signature helpKeyword="$.fn.datetimepicker.defaultDate">
-            ///<summary>Returns a moment with the options.defaultDate option configuration or false if not set</summary>
-            ///<returns type="Moment">date.clone()</returns>
-            ///</signature>
-            ///<signature>
-            ///<summary>Will set the picker's inital date. If a boolean:false value is passed the options.defaultDate parameter is cleared.</summary>
-            ///<param name="defaultDate" locid="$.fn.datetimepicker.defaultDate_p:defaultDate">Takes a string, Date, moment, boolean:false</param>
-            ///</signature>
-            if (arguments.length === 0) {
-                return options.defaultDate ? options.defaultDate.clone() : options.defaultDate;
-            }
-            if (!defaultDate) {
-                options.defaultDate = false;
-                return picker;
-            }
-
-            if (typeof defaultDate === 'string') {
-                if (defaultDate === 'now' || defaultDate === 'moment') {
-                    defaultDate = moment();
-                }
-            }
-
-            var parsedDate = parseInputDate(defaultDate);
-            if (!parsedDate.isValid()) {
-                throw new TypeError('defaultDate() Could not parse date parameter: ' + defaultDate);
-            }
-            if (!isValid(parsedDate)) {
-                throw new TypeError('defaultDate() date passed is invalid according to component setup validations');
-            }
-
-            options.defaultDate = parsedDate;
-
-            if (options.defaultDate && options.inline || (input.val().trim() === '' && input.attr('placeholder') === undefined)) {
-                setValue(options.defaultDate);
-            }
-            return picker;
-        };
-
-        picker.locale = function (locale) {
-            if (arguments.length === 0) {
-                return options.locale;
-            }
-
-            if (!moment.localeData(locale)) {
-                throw new TypeError('locale() locale ' + locale + ' is not loaded from moment locales!');
-            }
-
-            options.locale = locale;
-            date.locale(options.locale);
-            viewDate.locale(options.locale);
-
-            if (actualFormat) {
-                initFormatting(); // reinit formatting
-            }
-            if (widget) {
-                hide();
-                show();
-            }
-            return picker;
-        };
-
-        picker.stepping = function (stepping) {
-            if (arguments.length === 0) {
-                return options.stepping;
-            }
-
-            stepping = parseInt(stepping, 10);
-            if (isNaN(stepping) || stepping < 1) {
-                stepping = 1;
-            }
-            options.stepping = stepping;
-            return picker;
-        };
-
-        picker.useCurrent = function (useCurrent) {
-            var useCurrentOptions = ['year', 'month', 'day', 'hour', 'minute'];
-            if (arguments.length === 0) {
-                return options.useCurrent;
-            }
-
-            if ((typeof useCurrent !== 'boolean') && (typeof useCurrent !== 'string')) {
-                throw new TypeError('useCurrent() expects a boolean or string parameter');
-            }
-            if (typeof useCurrent === 'string' && useCurrentOptions.indexOf(useCurrent.toLowerCase()) === -1) {
-                throw new TypeError('useCurrent() expects a string parameter of ' + useCurrentOptions.join(', '));
-            }
-            options.useCurrent = useCurrent;
-            return picker;
-        };
-
-        picker.collapse = function (collapse) {
-            if (arguments.length === 0) {
-                return options.collapse;
-            }
-
-            if (typeof collapse !== 'boolean') {
-                throw new TypeError('collapse() expects a boolean parameter');
-            }
-            if (options.collapse === collapse) {
-                return picker;
-            }
-            options.collapse = collapse;
-            if (widget) {
-                hide();
-                show();
-            }
-            return picker;
-        };
-
-        picker.icons = function (icons) {
-            if (arguments.length === 0) {
-                return $.extend({}, options.icons);
-            }
-
-            if (!(icons instanceof Object)) {
-                throw new TypeError('icons() expects parameter to be an Object');
-            }
-            $.extend(options.icons, icons);
-            if (widget) {
-                hide();
-                show();
-            }
-            return picker;
-        };
-
-        picker.useStrict = function (useStrict) {
-            if (arguments.length === 0) {
-                return options.useStrict;
-            }
-
-            if (typeof useStrict !== 'boolean') {
-                throw new TypeError('useStrict() expects a boolean parameter');
-            }
-            options.useStrict = useStrict;
-            return picker;
-        };
-
-        picker.sideBySide = function (sideBySide) {
-            if (arguments.length === 0) {
-                return options.sideBySide;
-            }
-
-            if (typeof sideBySide !== 'boolean') {
-                throw new TypeError('sideBySide() expects a boolean parameter');
-            }
-            options.sideBySide = sideBySide;
-            if (widget) {
-                hide();
-                show();
-            }
-            return picker;
-        };
-
-        picker.viewMode = function (viewMode) {
-            if (arguments.length === 0) {
-                return options.viewMode;
-            }
-
-            if (typeof viewMode !== 'string') {
-                throw new TypeError('viewMode() expects a string parameter');
-            }
-
-            if (viewModes.indexOf(viewMode) === -1) {
-                throw new TypeError('viewMode() parameter must be one of (' + viewModes.join(', ') + ') value');
-            }
-
-            options.viewMode = viewMode;
-            currentViewMode = Math.max(viewModes.indexOf(viewMode), minViewModeNumber);
-
-            showMode();
-            return picker;
-        };
-
-        picker.toolbarPlacement = function (toolbarPlacement) {
-            if (arguments.length === 0) {
-                return options.toolbarPlacement;
-            }
-
-            if (typeof toolbarPlacement !== 'string') {
-                throw new TypeError('toolbarPlacement() expects a string parameter');
-            }
-            if (toolbarPlacements.indexOf(toolbarPlacement) === -1) {
-                throw new TypeError('toolbarPlacement() parameter must be one of (' + toolbarPlacements.join(', ') + ') value');
-            }
-            options.toolbarPlacement = toolbarPlacement;
-
-            if (widget) {
-                hide();
-                show();
-            }
-            return picker;
-        };
-
-        picker.widgetPositioning = function (widgetPositioning) {
-            if (arguments.length === 0) {
-                return $.extend({}, options.widgetPositioning);
-            }
-
-            if (({}).toString.call(widgetPositioning) !== '[object Object]') {
-                throw new TypeError('widgetPositioning() expects an object variable');
-            }
-            if (widgetPositioning.horizontal) {
-                if (typeof widgetPositioning.horizontal !== 'string') {
-                    throw new TypeError('widgetPositioning() horizontal variable must be a string');
-                }
-                widgetPositioning.horizontal = widgetPositioning.horizontal.toLowerCase();
-                if (horizontalModes.indexOf(widgetPositioning.horizontal) === -1) {
-                    throw new TypeError('widgetPositioning() expects horizontal parameter to be one of (' + horizontalModes.join(', ') + ')');
-                }
-                options.widgetPositioning.horizontal = widgetPositioning.horizontal;
-            }
-            if (widgetPositioning.vertical) {
-                if (typeof widgetPositioning.vertical !== 'string') {
-                    throw new TypeError('widgetPositioning() vertical variable must be a string');
-                }
-                widgetPositioning.vertical = widgetPositioning.vertical.toLowerCase();
-                if (verticalModes.indexOf(widgetPositioning.vertical) === -1) {
-                    throw new TypeError('widgetPositioning() expects vertical parameter to be one of (' + verticalModes.join(', ') + ')');
-                }
-                options.widgetPositioning.vertical = widgetPositioning.vertical;
-            }
-            update();
-            return picker;
-        };
-
-        picker.calendarWeeks = function (calendarWeeks) {
-            if (arguments.length === 0) {
-                return options.calendarWeeks;
-            }
-
-            if (typeof calendarWeeks !== 'boolean') {
-                throw new TypeError('calendarWeeks() expects parameter to be a boolean value');
-            }
-
-            options.calendarWeeks = calendarWeeks;
-            update();
-            return picker;
-        };
-
-        picker.showTodayButton = function (showTodayButton) {
-            if (arguments.length === 0) {
-                return options.showTodayButton;
-            }
-
-            if (typeof showTodayButton !== 'boolean') {
-                throw new TypeError('showTodayButton() expects a boolean parameter');
-            }
-
-            options.showTodayButton = showTodayButton;
-            if (widget) {
-                hide();
-                show();
-            }
-            return picker;
-        };
-
-        picker.showClear = function (showClear) {
-            if (arguments.length === 0) {
-                return options.showClear;
-            }
-
-            if (typeof showClear !== 'boolean') {
-                throw new TypeError('showClear() expects a boolean parameter');
-            }
-
-            options.showClear = showClear;
-            if (widget) {
-                hide();
-                show();
-            }
-            return picker;
-        };
-
-        picker.widgetParent = function (widgetParent) {
-            if (arguments.length === 0) {
-                return options.widgetParent;
-            }
-
-            if (typeof widgetParent === 'string') {
-                widgetParent = $(widgetParent);
-            }
-
-            if (widgetParent !== null && (typeof widgetParent !== 'string' && !(widgetParent instanceof $))) {
-                throw new TypeError('widgetParent() expects a string or a jQuery object parameter');
-            }
-
-            options.widgetParent = widgetParent;
-            if (widget) {
-                hide();
-                show();
-            }
-            return picker;
-        };
-
-        picker.keepOpen = function (keepOpen) {
-            if (arguments.length === 0) {
-                return options.keepOpen;
-            }
-
-            if (typeof keepOpen !== 'boolean') {
-                throw new TypeError('keepOpen() expects a boolean parameter');
-            }
-
-            options.keepOpen = keepOpen;
-            return picker;
-        };
-
-        picker.focusOnShow = function (focusOnShow) {
-            if (arguments.length === 0) {
-                return options.focusOnShow;
-            }
-
-            if (typeof focusOnShow !== 'boolean') {
-                throw new TypeError('focusOnShow() expects a boolean parameter');
-            }
-
-            options.focusOnShow = focusOnShow;
-            return picker;
-        };
-
-        picker.inline = function (inline) {
-            if (arguments.length === 0) {
-                return options.inline;
-            }
-
-            if (typeof inline !== 'boolean') {
-                throw new TypeError('inline() expects a boolean parameter');
-            }
-
-            options.inline = inline;
-            return picker;
-        };
-
-        picker.clear = function () {
-            clear();
-            return picker;
-        };
-
-        picker.keyBinds = function (keyBinds) {
-            options.keyBinds = keyBinds;
-            return picker;
-        };
-
-        picker.debug = function (debug) {
-            if (typeof debug !== 'boolean') {
-                throw new TypeError('debug() expects a boolean parameter');
-            }
-
-            options.debug = debug;
-            return picker;
-        };
-
-        picker.allowInputToggle = function (allowInputToggle) {
-            if (arguments.length === 0) {
-                return options.allowInputToggle;
-            }
-
-            if (typeof allowInputToggle !== 'boolean') {
-                throw new TypeError('allowInputToggle() expects a boolean parameter');
-            }
-
-            options.allowInputToggle = allowInputToggle;
-            return picker;
-        };
-
-        picker.showClose = function (showClose) {
-            if (arguments.length === 0) {
-                return options.showClose;
-            }
-
-            if (typeof showClose !== 'boolean') {
-                throw new TypeError('showClose() expects a boolean parameter');
-            }
-
-            options.showClose = showClose;
-            return picker;
-        };
-
-        picker.keepInvalid = function (keepInvalid) {
-            if (arguments.length === 0) {
-                return options.keepInvalid;
-            }
-
-            if (typeof keepInvalid !== 'boolean') {
-                throw new TypeError('keepInvalid() expects a boolean parameter');
-            }
-            options.keepInvalid = keepInvalid;
-            return picker;
-        };
-
-        picker.datepickerInput = function (datepickerInput) {
-            if (arguments.length === 0) {
-                return options.datepickerInput;
-            }
-
-            if (typeof datepickerInput !== 'string') {
-                throw new TypeError('datepickerInput() expects a string parameter');
-            }
-
-            options.datepickerInput = datepickerInput;
-            return picker;
-        };
-
-        picker.parseInputDate = function (parseInputDate) {
-            if (arguments.length === 0) {
-                return options.parseInputDate;
-            }
-
-            if (typeof parseInputDate !== 'function') {
-                throw new TypeError('parseInputDate() sholud be as function');
-            }
-
-            options.parseInputDate = parseInputDate;
-
-            return picker;
-        };
-
-        picker.disabledTimeIntervals = function (disabledTimeIntervals) {
-            ///<signature helpKeyword="$.fn.datetimepicker.disabledTimeIntervals">
-            ///<summary>Returns an array with the currently set disabled dates on the component.</summary>
-            ///<returns type="array">options.disabledTimeIntervals</returns>
-            ///</signature>
-            ///<signature>
-            ///<summary>Setting this takes precedence over options.minDate, options.maxDate configuration. Also calling this function removes the configuration of
-            ///options.enabledDates if such exist.</summary>
-            ///<param name="dates" locid="$.fn.datetimepicker.disabledTimeIntervals_p:dates">Takes an [ string or Date or moment ] of values and allows the user to select only from those days.</param>
-            ///</signature>
-            if (arguments.length === 0) {
-                return (options.disabledTimeIntervals ? $.extend({}, options.disabledTimeIntervals) : options.disabledTimeIntervals);
-            }
-
-            if (!disabledTimeIntervals) {
-                options.disabledTimeIntervals = false;
-                update();
-                return picker;
-            }
-            if (!(disabledTimeIntervals instanceof Array)) {
-                throw new TypeError('disabledTimeIntervals() expects an array parameter');
-            }
-            options.disabledTimeIntervals = disabledTimeIntervals;
-            update();
-            return picker;
-        };
-
-        picker.disabledHours = function (hours) {
-            ///<signature helpKeyword="$.fn.datetimepicker.disabledHours">
-            ///<summary>Returns an array with the currently set disabled hours on the component.</summary>
-            ///<returns type="array">options.disabledHours</returns>
-            ///</signature>
-            ///<signature>
-            ///<summary>Setting this takes precedence over options.minDate, options.maxDate configuration. Also calling this function removes the configuration of
-            ///options.enabledHours if such exist.</summary>
-            ///<param name="hours" locid="$.fn.datetimepicker.disabledHours_p:hours">Takes an [ int ] of values and disallows the user to select only from those hours.</param>
-            ///</signature>
-            if (arguments.length === 0) {
-                return (options.disabledHours ? $.extend({}, options.disabledHours) : options.disabledHours);
-            }
-
-            if (!hours) {
-                options.disabledHours = false;
-                update();
-                return picker;
-            }
-            if (!(hours instanceof Array)) {
-                throw new TypeError('disabledHours() expects an array parameter');
-            }
-            options.disabledHours = indexGivenHours(hours);
-            options.enabledHours = false;
-            if (options.useCurrent && !options.keepInvalid) {
-                var tries = 0;
-                while (!isValid(date, 'h')) {
-                    date.add(1, 'h');
-                    if (tries === 24) {
-                        throw 'Tried 24 times to find a valid date';
-                    }
-                    tries++;
-                }
-                setValue(date);
-            }
-            update();
-            return picker;
-        };
-
-        picker.enabledHours = function (hours) {
-            ///<signature helpKeyword="$.fn.datetimepicker.enabledHours">
-            ///<summary>Returns an array with the currently set enabled hours on the component.</summary>
-            ///<returns type="array">options.enabledHours</returns>
-            ///</signature>
-            ///<signature>
-            ///<summary>Setting this takes precedence over options.minDate, options.maxDate configuration. Also calling this function removes the configuration of options.disabledHours if such exist.</summary>
-            ///<param name="hours" locid="$.fn.datetimepicker.enabledHours_p:hours">Takes an [ int ] of values and allows the user to select only from those hours.</param>
-            ///</signature>
-            if (arguments.length === 0) {
-                return (options.enabledHours ? $.extend({}, options.enabledHours) : options.enabledHours);
-            }
-
-            if (!hours) {
-                options.enabledHours = false;
-                update();
-                return picker;
-            }
-            if (!(hours instanceof Array)) {
-                throw new TypeError('enabledHours() expects an array parameter');
-            }
-            options.enabledHours = indexGivenHours(hours);
-            options.disabledHours = false;
-            if (options.useCurrent && !options.keepInvalid) {
-                var tries = 0;
-                while (!isValid(date, 'h')) {
-                    date.add(1, 'h');
-                    if (tries === 24) {
-                        throw 'Tried 24 times to find a valid date';
-                    }
-                    tries++;
-                }
-                setValue(date);
-            }
-            update();
-            return picker;
-        };
-
-        picker.viewDate = function (newDate) {
-            ///<signature helpKeyword="$.fn.datetimepicker.viewDate">
-            ///<summary>Returns the component's model current viewDate, a moment object or null if not set.</summary>
-            ///<returns type="Moment">viewDate.clone()</returns>
-            ///</signature>
-            ///<signature>
-            ///<summary>Sets the components model current moment to it. Passing a null value unsets the components model current moment. Parsing of the newDate parameter is made using moment library with the options.format and options.useStrict components configuration.</summary>
-            ///<param name="newDate" locid="$.fn.datetimepicker.date_p:newDate">Takes string, viewDate, moment, null parameter.</param>
-            ///</signature>
-            if (arguments.length === 0) {
-                return viewDate.clone();
-            }
-
-            if (!newDate) {
-                viewDate = date.clone();
-                return picker;
-            }
-
-            if (typeof newDate !== 'string' && !moment.isMoment(newDate) && !(newDate instanceof Date)) {
-                throw new TypeError('viewDate() parameter must be one of [string, moment or Date]');
-            }
-
-            viewDate = parseInputDate(newDate);
-            viewUpdate();
-            return picker;
-        };
-
-        // initializing element and component attributes
-        if (element.is('input')) {
-            input = element;
-        } else {
-            input = element.find(options.datepickerInput);
-            if (input.size() === 0) {
-                input = element.find('input');
-            } else if (!input.is('input')) {
-                throw new Error('CSS class "' + options.datepickerInput + '" cannot be applied to non input element');
-            }
-        }
-
-        if (element.hasClass('input-group')) {
-            // in case there is more then one 'input-group-addon' Issue #48
-            if (element.find('.datepickerbutton').size() === 0) {
-                component = element.find('[class^="input-group-"]');
-            } else {
-                component = element.find('.datepickerbutton');
-            }
-        }
-
-        if (!options.inline && !input.is('input')) {
-            throw new Error('Could not initialize DateTimePicker without an input element');
-        }
-
-        $.extend(true, options, dataToOptions());
-
-        picker.options(options);
-
-        initFormatting();
-
-        attachDatePickerElementEvents();
-
-        if (input.prop('disabled')) {
-            picker.disable();
-        }
-        if (input.is('input') && input.val().trim().length !== 0) {
-            setValue(parseInputDate(input.val().trim()));
-        }
-        else if (options.defaultDate && input.attr('placeholder') === undefined) {
-            setValue(options.defaultDate);
-        }
-        if (options.inline) {
-            show();
-        }
-        return picker;
-    };
-
-    /********************************************************************************
-     *
-     * jQuery plugin constructor and defaults object
-     *
-     ********************************************************************************/
-
-    $.fn.datetimepicker = function (options) {
-        return this.each(function () {
-            var $this = $(this);
-            if (!$this.data('DateTimePicker')) {
-                // create a private copy of the defaults object
-                options = $.extend(true, {}, $.fn.datetimepicker.defaults, options);
-                $this.data('DateTimePicker', dateTimePicker($this, options));
-            }
-        });
-    };
-
-    $.fn.datetimepicker.defaults = {
-        format: false,
-        dayViewHeaderFormat: 'MMMM YYYY',
-        extraFormats: false,
-        stepping: 1,
-        minDate: false,
-        maxDate: false,
-        useCurrent: true,
-        collapse: true,
-        locale: moment.locale(),
-        defaultDate: false,
-        disabledDates: false,
-        enabledDates: false,
-        icons: {
-            time: 'glyphicon glyphicon-time',
-            date: 'glyphicon glyphicon-calendar',
-            up: 'glyphicon glyphicon-chevron-up',
-            down: 'glyphicon glyphicon-chevron-down',
-            previous: 'glyphicon glyphicon-chevron-left',
-            next: 'glyphicon glyphicon-chevron-right',
-            today: 'glyphicon glyphicon-screenshot',
-            clear: 'glyphicon glyphicon-trash',
-            close: 'glyphicon glyphicon-remove'
-        },
-        useStrict: false,
-        sideBySide: false,
-        daysOfWeekDisabled: false,
-        calendarWeeks: false,
-        viewMode: 'days',
-        toolbarPlacement: 'default',
-        showTodayButton: false,
-        showClear: false,
-        showClose: false,
-        widgetPositioning: {
-            horizontal: 'auto',
-            vertical: 'auto'
-        },
-        widgetParent: null,
-        ignoreReadonly: false,
-        keepOpen: false,
-        focusOnShow: true,
-        inline: false,
-        keepInvalid: false,
-        datepickerInput: '.datepickerinput',
-        keyBinds: {
-            up: function (widget) {
-                if (!widget) {
-                    return;
-                }
-                var d = this.date() || moment();
-                if (widget.find('.datepicker').is(':visible')) {
-                    this.date(d.clone().subtract(7, 'd'));
-                } else {
-                    this.date(d.clone().add(1, 'm'));
-                }
-            },
-            down: function (widget) {
-                if (!widget) {
-                    this.show();
-                    return;
-                }
-                var d = this.date() || moment();
-                if (widget.find('.datepicker').is(':visible')) {
-                    this.date(d.clone().add(7, 'd'));
-                } else {
-                    this.date(d.clone().subtract(1, 'm'));
-                }
-            },
-            'control up': function (widget) {
-                if (!widget) {
-                    return;
-                }
-                var d = this.date() || moment();
-                if (widget.find('.datepicker').is(':visible')) {
-                    this.date(d.clone().subtract(1, 'y'));
-                } else {
-                    this.date(d.clone().add(1, 'h'));
-                }
-            },
-            'control down': function (widget) {
-                if (!widget) {
-                    return;
-                }
-                var d = this.date() || moment();
-                if (widget.find('.datepicker').is(':visible')) {
-                    this.date(d.clone().add(1, 'y'));
-                } else {
-                    this.date(d.clone().subtract(1, 'h'));
-                }
-            },
-            left: function (widget) {
-                if (!widget) {
-                    return;
-                }
-                var d = this.date() || moment();
-                if (widget.find('.datepicker').is(':visible')) {
-                    this.date(d.clone().subtract(1, 'd'));
-                }
-            },
-            right: function (widget) {
-                if (!widget) {
-                    return;
-                }
-                var d = this.date() || moment();
-                if (widget.find('.datepicker').is(':visible')) {
-                    this.date(d.clone().add(1, 'd'));
-                }
-            },
-            pageUp: function (widget) {
-                if (!widget) {
-                    return;
-                }
-                var d = this.date() || moment();
-                if (widget.find('.datepicker').is(':visible')) {
-                    this.date(d.clone().subtract(1, 'M'));
-                }
-            },
-            pageDown: function (widget) {
-                if (!widget) {
-                    return;
-                }
-                var d = this.date() || moment();
-                if (widget.find('.datepicker').is(':visible')) {
-                    this.date(d.clone().add(1, 'M'));
-                }
-            },
-            enter: function () {
-                this.hide();
-            },
-            escape: function () {
-                this.hide();
-            },
-            //tab: function (widget) { //this break the flow of the form. disabling for now
-            //    var toggle = widget.find('.picker-switch a[data-action="togglePicker"]');
-            //    if(toggle.length > 0) toggle.click();
-            //},
-            'control space': function (widget) {
-                if (widget.find('.timepicker').is(':visible')) {
-                    widget.find('.btn[data-action="togglePeriod"]').click();
-                }
-            },
-            t: function () {
-                this.date(moment());
-            },
-            'delete': function () {
-                this.clear();
-            }
-        },
-        debug: false,
-        allowInputToggle: false,
-        disabledTimeIntervals: false,
-        disabledHours: false,
-        enabledHours: false,
-        viewDate: false
-    };
-}));
\ No newline at end of file
diff --git a/dashboardv2/public/js/external_lib/datetimepicker/bootstrap-datetimepicker.min.css b/dashboardv2/public/js/external_lib/datetimepicker/bootstrap-datetimepicker.min.css
deleted file mode 100644
index e9ec816..0000000
--- a/dashboardv2/public/js/external_lib/datetimepicker/bootstrap-datetimepicker.min.css
+++ /dev/null
@@ -1,5 +0,0 @@
-/*!
- * Datetimepicker for Bootstrap 3
- * version : 4.14.30
- * https://github.com/Eonasdan/bootstrap-datetimepicker/
- */.bootstrap-datetimepicker-widget{list-style:none}.bootstrap-datetimepicker-widget.dropdown-menu{margin:2px 0;padding:4px;width:19em}@media (min-width:768px){.bootstrap-datetimepicker-widget.dropdown-menu.timepicker-sbs{width:38em}}@media (min-width:992px){.bootstrap-datetimepicker-widget.dropdown-menu.timepicker-sbs{width:38em}}@media (min-width:1200px){.bootstrap-datetimepicker-widget.dropdown-menu.timepicker-sbs{width:38em}}.bootstrap-datetimepicker-widget.dropdown-menu:after,.bootstrap-datetimepicker-widget.dropdown-menu:before{content:'';display:inline-block;position:absolute}.bootstrap-datetimepicker-widget.dropdown-menu.bottom:before{border-left:7px solid transparent;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-bottom-color:rgba(0,0,0,.2);top:-7px;left:7px}.bootstrap-datetimepicker-widget.dropdown-menu.bottom:after{border-left:6px solid transparent;border-right:6px solid transparent;border-bottom:6px solid #fff;top:-6px;left:8px}.bootstrap-datetimepicker-widget.dropdown-menu.top:before{border-left:7px solid transparent;border-right:7px solid transparent;border-top:7px solid #ccc;border-top-color:rgba(0,0,0,.2);bottom:-7px;left:6px}.bootstrap-datetimepicker-widget.dropdown-menu.top:after{border-left:6px solid transparent;border-right:6px solid transparent;border-top:6px solid #fff;bottom:-6px;left:7px}.bootstrap-datetimepicker-widget.dropdown-menu.pull-right:before{left:auto;right:6px}.bootstrap-datetimepicker-widget.dropdown-menu.pull-right:after{left:auto;right:7px}.bootstrap-datetimepicker-widget .list-unstyled{margin:0}.bootstrap-datetimepicker-widget a[data-action]{padding:6px 0}.bootstrap-datetimepicker-widget a[data-action]:active{box-shadow:none}.bootstrap-datetimepicker-widget .timepicker-hour,.bootstrap-datetimepicker-widget .timepicker-minute,.bootstrap-datetimepicker-widget .timepicker-second{width:54px;font-weight:700;font-size:1.2em;margin:0}.bootstrap-datetimepicker-widget button[data-action]{padding:6px}.bootstrap-datetimepicker-widget .btn[data-action=incrementHours]::after{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);border:0;content:"Increment Hours"}.bootstrap-datetimepicker-widget .btn[data-action=incrementMinutes]::after{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);border:0;content:"Increment Minutes"}.bootstrap-datetimepicker-widget .btn[data-action=decrementHours]::after{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);border:0;content:"Decrement Hours"}.bootstrap-datetimepicker-widget .btn[data-action=decrementMinutes]::after{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);border:0;content:"Decrement Minutes"}.bootstrap-datetimepicker-widget .btn[data-action=showHours]::after{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);border:0;content:"Show Hours"}.bootstrap-datetimepicker-widget .btn[data-action=showMinutes]::after{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);border:0;content:"Show Minutes"}.bootstrap-datetimepicker-widget .btn[data-action=togglePeriod]::after{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);border:0;content:"Toggle AM/PM"}.bootstrap-datetimepicker-widget .btn[data-action=clear]::after{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);border:0;content:"Clear the picker"}.bootstrap-datetimepicker-widget .btn[data-action=today]::after{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);border:0;content:"Set the date to today"}.bootstrap-datetimepicker-widget .picker-switch{text-align:center}.bootstrap-datetimepicker-widget .picker-switch::after{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);border:0;content:"Toggle Date and Time Screens"}.bootstrap-datetimepicker-widget .picker-switch td{padding:0;margin:0;height:auto;width:auto;line-height:inherit}.bootstrap-datetimepicker-widget .picker-switch td span{line-height:2.5;height:2.5em;width:100%}.bootstrap-datetimepicker-widget table{width:100%;margin:0}.bootstrap-datetimepicker-widget table td,.bootstrap-datetimepicker-widget table th{text-align:center;border-radius:4px}.bootstrap-datetimepicker-widget table th{height:20px;line-height:20px;width:20px}.bootstrap-datetimepicker-widget table th.picker-switch{width:145px}.bootstrap-datetimepicker-widget table th.disabled,.bootstrap-datetimepicker-widget table th.disabled:hover{background:0 0;color:#777;cursor:not-allowed}.bootstrap-datetimepicker-widget table th.prev::after{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);border:0;content:"Previous Month"}.bootstrap-datetimepicker-widget table th.next::after{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);border:0;content:"Next Month"}.bootstrap-datetimepicker-widget table thead tr:first-child th{cursor:pointer}.bootstrap-datetimepicker-widget table thead tr:first-child th:hover{background:#eee}.bootstrap-datetimepicker-widget table td{height:54px;line-height:54px;width:54px}.bootstrap-datetimepicker-widget table td.cw{font-size:.8em;height:20px;line-height:20px;color:#777}.bootstrap-datetimepicker-widget table td.day{height:20px;line-height:20px;width:20px}.bootstrap-datetimepicker-widget table td.day:hover,.bootstrap-datetimepicker-widget table td.hour:hover,.bootstrap-datetimepicker-widget table td.minute:hover,.bootstrap-datetimepicker-widget table td.second:hover{background:#eee;cursor:pointer}.bootstrap-datetimepicker-widget table td.new,.bootstrap-datetimepicker-widget table td.old{color:#777}.bootstrap-datetimepicker-widget table td.today{position:relative}.bootstrap-datetimepicker-widget table td.today:before{content:'';display:inline-block;border:0 solid transparent;border-bottom-color:#337ab7;border-top-color:rgba(0,0,0,.2);position:absolute;bottom:4px;right:4px}.bootstrap-datetimepicker-widget table td.active,.bootstrap-datetimepicker-widget table td.active:hover{background-color:#337ab7;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,.25)}.bootstrap-datetimepicker-widget table td.active.today:before{border-bottom-color:#fff}.bootstrap-datetimepicker-widget table td.disabled,.bootstrap-datetimepicker-widget table td.disabled:hover{background:0 0;color:#777;cursor:not-allowed}.bootstrap-datetimepicker-widget table td span{display:inline-block;width:54px;height:54px;line-height:54px;margin:2px 1.5px;cursor:pointer;border-radius:4px}.bootstrap-datetimepicker-widget table td span:hover{background:#eee}.bootstrap-datetimepicker-widget table td span.active{background-color:#337ab7;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,.25)}.bootstrap-datetimepicker-widget table td span.old{color:#777}.bootstrap-datetimepicker-widget table td span.disabled,.bootstrap-datetimepicker-widget table td span.disabled:hover{background:0 0;color:#777;cursor:not-allowed}.bootstrap-datetimepicker-widget.usetwentyfour td.hour{height:27px;line-height:27px}.bootstrap-datetimepicker-widget.wider{width:21em}.bootstrap-datetimepicker-widget .datepicker-decades .decade{line-height:1.8em!important}.input-group.date .input-group-addon{cursor:pointer}.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);border:0}
\ No newline at end of file
diff --git a/dashboardv2/public/js/main.js b/dashboardv2/public/js/main.js
index 3b40451..9235d28 100644
--- a/dashboardv2/public/js/main.js
+++ b/dashboardv2/public/js/main.js
@@ -94,10 +94,6 @@
             'deps': ['d3'],
             'exports': ['d3-tip']
         },
-        'datetimepicker': {
-            'deps': ['jquery'],
-            'exports': 'datetimepicker'
-        },
         'dagreD3': {
             'deps': ['d3'],
             'exports': ['dagreD3']
@@ -107,6 +103,12 @@
         },
         'jquery-placeholder': {
             'deps': ['jquery']
+        },
+        'query-builder': {
+            'deps': ['jquery']
+        },
+        'daterangepicker': {
+            'deps': ['jquery', 'moment']
         }
     },
 
@@ -137,12 +139,13 @@
         'backgrid-select-all': 'libs/backgrid-select-all/backgrid-select-all.min',
         'moment': 'libs/moment/js/moment.min',
         'jquery-ui': 'external_lib/jquery-ui/jquery-ui.min',
-        'datetimepicker': 'external_lib/datetimepicker/bootstrap-datetimepicker',
         'pnotify': 'external_lib/pnotify/pnotify.custom.min',
         'pnotify.buttons': 'external_lib/pnotify/pnotify.custom.min',
         'pnotify.confirm': 'external_lib/pnotify/pnotify.custom.min',
         'jquery-placeholder': 'libs/jquery-placeholder/js/jquery.placeholder',
-        'platform': 'libs/platform/platform'
+        'platform': 'libs/platform/platform',
+        'query-builder': 'libs/jQueryQueryBuilder/js/query-builder.standalone.min',
+        'daterangepicker': 'libs/bootstrap-daterangepicker/js/daterangepicker'
     },
 
     /**
@@ -167,7 +170,7 @@
     'select2'
 ], function(App, Router, CommonViewFunction, Globals, UrlLinks, VEntityList, VTagList) {
     var that = this;
-    this.asyncFetchCounter = 4;
+    this.asyncFetchCounter = 5;
     this.entityDefCollection = new VEntityList();
     this.entityDefCollection.url = UrlLinks.entitiesDefApiUrl();
     this.typeHeaders = new VTagList();
@@ -175,11 +178,13 @@
     this.enumDefCollection = new VTagList();
     this.enumDefCollection.url = UrlLinks.enumDefApiUrl();
     this.enumDefCollection.modelAttrName = "enumDefs";
+    this.classificationDefCollection = new VTagList();
 
     App.appRouter = new Router({
         entityDefCollection: this.entityDefCollection,
         typeHeaders: this.typeHeaders,
-        enumDefCollection: this.enumDefCollection
+        enumDefCollection: this.enumDefCollection,
+        classificationDefCollection: this.classificationDefCollection
     });
 
     var startApp = function() {
@@ -238,4 +243,11 @@
             startApp();
         }
     });
+    this.classificationDefCollection.fetch({
+        skipDefaultError: true,
+        complete: function() {
+            --that.asyncFetchCounter;
+            startApp();
+        }
+    });
 });
diff --git a/dashboardv2/public/js/models/VSearch.js b/dashboardv2/public/js/models/VSearch.js
index 5c3df97..700a909 100644
--- a/dashboardv2/public/js/models/VSearch.js
+++ b/dashboardv2/public/js/models/VSearch.js
@@ -49,7 +49,7 @@
             }, options);
 
             return this.constructor.nonCrudOperation.call(this, url, 'GET', options);
-        },
+        }
     }, {});
     return VSearch;
 });
diff --git a/dashboardv2/public/js/models/VTag.js b/dashboardv2/public/js/models/VTag.js
index c875d5a..65010cf 100644
--- a/dashboardv2/public/js/models/VTag.js
+++ b/dashboardv2/public/js/models/VTag.js
@@ -23,7 +23,7 @@
 ], function(require, Globals, vBaseModel, UrlLinks) {
     'use strict';
     var VTag = vBaseModel.extend({
-        urlRoot: UrlLinks.typesClassicationApiUrl(),
+        urlRoot: UrlLinks.classificationDefApiUrl(),
 
         defaults: {},
 
@@ -49,7 +49,7 @@
             return this.constructor.nonCrudOperation.call(this, url, 'DELETE', options);
         },
         deleteTag: function(options) {
-            var url = UrlLinks.typesClassicationApiUrl();
+            var url = UrlLinks.classificationDefApiUrl();
             options = _.extend({
                 contentType: 'application/json',
                 dataType: 'json'
@@ -57,7 +57,7 @@
             return this.constructor.nonCrudOperation.call(this, url, 'DELETE', options);
         },
         saveTagAttribute: function(options) {
-            var url = UrlLinks.typesClassicationApiUrl();
+            var url = UrlLinks.classificationDefApiUrl();
             options = _.extend({
                 contentType: 'application/json',
                 dataType: 'json'
diff --git a/dashboardv2/public/js/router/Router.js b/dashboardv2/public/js/router/Router.js
index f1250e7..8a1d241 100644
--- a/dashboardv2/public/js/router/Router.js
+++ b/dashboardv2/public/js/router/Router.js
@@ -42,16 +42,16 @@
             '*actions': 'defaultAction'
         },
         initialize: function(options) {
-            _.extend(this, _.pick(options, 'entityDefCollection', 'typeHeaders', 'enumDefCollection'));
+            _.extend(this, _.pick(options, 'entityDefCollection', 'typeHeaders', 'enumDefCollection', 'classificationDefCollection'));
             this.showRegions();
             this.bindCommonEvents();
             this.listenTo(this, 'route', this.postRouteExecute, this);
-            this.tagCollection = new VTagList();
             this.searchVent = new Backbone.Wreqr.EventAggregator();
             this.preFetchedCollectionLists = {
                 'entityDefCollection': this.entityDefCollection,
                 'typeHeaders': this.typeHeaders,
-                'enumDefCollection': this.enumDefCollection
+                'enumDefCollection': this.enumDefCollection,
+                'classificationDefCollection': this.classificationDefCollection
             }
         },
         bindCommonEvents: function() {
@@ -125,7 +125,6 @@
                         App.rSideNav.show(new SideNavLayoutView(
                             _.extend({
                                 'url': url,
-                                'collection': that.tagCollection
                             }, that.preFetchedCollectionLists)
                         ));
                     } else {
@@ -157,9 +156,7 @@
                     App.rNHeader.show(new Header());
                     if (!App.rSideNav.currentView) {
                         App.rSideNav.show(new SideNavLayoutView(
-                            _.extend({
-                                'collection': that.tagCollection,
-                            }, that.preFetchedCollectionLists)
+                            _.extend({}, that.preFetchedCollectionLists)
                         ));
                     } else {
                         App.rSideNav.currentView.selectTab();
@@ -196,8 +193,7 @@
                     }
                     App.rSideNav.show(new SideNavLayoutView(
                         _.extend({
-                            'tag': tagName,
-                            'collection': that.tagCollection
+                            'tag': tagName
                         }, that.preFetchedCollectionLists)
                     ));
                 } else {
@@ -221,8 +217,7 @@
                     }
                     App.rNContent.show(new TagDetailLayoutView(
                         _.extend({
-                            'tag': tagName,
-                            'collection': that.tagCollection,
+                            'tag': tagName
                         }, that.preFetchedCollectionLists)
                     ));
                 }
@@ -236,12 +231,17 @@
                 'views/business_catalog/SideNavLayoutView',
                 'views/search/SearchDetailLayoutView',
             ], function(Header, BusinessCatalogLayoutView, SideNavLayoutView, SearchDetailLayoutView) {
-                var paramObj = Utils.getUrlState.getQueryParams();
+                var paramObj = Utils.getUrlState.getQueryParams(),
+                    filterObj = {
+                        'tagFilters': JSON.parse(Utils.localStorage.getValue('tagFilters')),
+                        'entityFilters': JSON.parse(Utils.localStorage.getValue('entityFilters'))
+                    }
                 App.rNHeader.show(new Header());
                 if (!App.rSideNav.currentView) {
                     App.rSideNav.show(new SideNavLayoutView(
                         _.extend({
-                            'collection': that.tagCollection
+                            'searchVent': that.searchVent,
+                            'filterObj': filterObj
                         }, that.preFetchedCollectionLists)
                     ));
                 } else {
@@ -256,7 +256,9 @@
                     App.rNContent.show(new SearchDetailLayoutView(
                         _.extend({
                             'value': paramObj,
-                            'initialView': true
+                            'initialView': true,
+                            'filterObj': filterObj,
+                            'searchVent': that.searchVent
                         }, that.preFetchedCollectionLists)
                     ));
                 } else {
@@ -273,14 +275,42 @@
                 'views/business_catalog/SideNavLayoutView',
                 'views/search/SearchDetailLayoutView'
             ], function(Header, BusinessCatalogLayoutView, SideNavLayoutView, SearchDetailLayoutView) {
-                var paramObj = Utils.getUrlState.getQueryParams();
+                var paramObj = Utils.getUrlState.getQueryParams(),
+                    filterObj = {
+                        'tagFilters': JSON.parse(Utils.localStorage.getValue('tagFilters')),
+                        'entityFilters': JSON.parse(Utils.localStorage.getValue('entityFilters'))
+                    }
+                if (paramObj && paramObj.searchType === "basic") {
+                    if (paramObj.type) {
+                        if (_.has(filterObj.entityFilters, paramObj.type)) {
+                            _.extend(paramObj, {
+                                'entityFilters': +new Date()
+                            })
+                        }
+                    }
+                    if (paramObj.tag) {
+                        if (_.has(filterObj.entityFilters, paramObj.type)) {
+                            _.extend(paramObj, {
+                                'tagFilters': +new Date()
+                            })
+                        }
+                    }
+                    Utils.setUrl({
+                        url: '#!/search/searchResult',
+                        trigger: false,
+                        urlParams: paramObj,
+                        updateTabState: function() {
+                            return { searchUrl: this.url, stateChanged: true };
+                        },
+                    });
+                }
                 App.rNHeader.show(new Header());
                 if (!App.rSideNav.currentView) {
                     App.rSideNav.show(new SideNavLayoutView(
                         _.extend({
                             'value': paramObj,
-                            'collection': that.tagCollection,
-                            'searchVent': that.searchVent
+                            'searchVent': that.searchVent,
+                            'filterObj': filterObj
                         }, that.preFetchedCollectionLists)
                     ));
                 } else {
@@ -291,6 +321,7 @@
                     _.extend({
                         'value': paramObj,
                         'searchVent': that.searchVent,
+                        'filterObj': filterObj,
                         'initialView': (paramObj.type || (paramObj.dslChecked == "true" ? "" : paramObj.tag) || (paramObj.query ? paramObj.query.trim() : "")).length === 0
                     }, that.preFetchedCollectionLists)
                 ));
diff --git a/dashboardv2/public/js/templates/search/QueryBuilder_tmpl.html b/dashboardv2/public/js/templates/search/QueryBuilder_tmpl.html
new file mode 100644
index 0000000..f204390
--- /dev/null
+++ b/dashboardv2/public/js/templates/search/QueryBuilder_tmpl.html
@@ -0,0 +1,17 @@
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<div id="builder"></div>
diff --git a/dashboardv2/public/js/templates/search/SearchLayoutView_tmpl.html b/dashboardv2/public/js/templates/search/SearchLayoutView_tmpl.html
index a766cdf..a23057f 100644
--- a/dashboardv2/public/js/templates/search/SearchLayoutView_tmpl.html
+++ b/dashboardv2/public/js/templates/search/SearchLayoutView_tmpl.html
@@ -33,16 +33,26 @@
     </div>
     <div class="col-sm-12">
         <div class="form-group">
-            <div class="srchType">
+            <div class="srchType clearfix">
                 <span class="srchTitle">Search By Type</span>
-                <div class="typeLOV">
-                    <select data-id="typeLOV"></select>
+                <div class="">
+                    <div class="col-sm-10 no-padding temFilter">
+                        <select data-id="typeLOV"></select>
+                    </div>
+                    <div class="col-sm-2 no-padding temFilterBtn">
+                        <button type="button" class="btn btn-atlasAction btn-atlas pull-right typeLOV" title="Entity Attribute Filter" data-id="typeAttrFilter"><i class="fa fa-filter"></i></button>
+                    </div>
                 </div>
             </div>
-            <div class="srchType tagBox">
+            <div class="srchType tagBox clearfix">
                 <span class="srchTitle">Search By Tag</span>
-                <div class="typeLOV">
-                    <select data-id="tagLOV"></select>
+                <div>
+                    <div class="col-sm-10 no-padding">
+                        <select data-id="tagLOV"></select>
+                    </div>
+                    <div class="col-sm-2 no-padding">
+                        <button type="button" class="btn btn-atlasAction btn-atlas pull-right" title="Tag Attribute Filter" data-id="tagAttrFilter"><i class="fa fa-filter"></i></button>
+                    </div>
                 </div>
             </div>
             <div class="srchType">
diff --git a/dashboardv2/public/js/templates/search/SearchQuery_tmpl.html b/dashboardv2/public/js/templates/search/SearchQuery_tmpl.html
new file mode 100644
index 0000000..05c2a61
--- /dev/null
+++ b/dashboardv2/public/js/templates/search/SearchQuery_tmpl.html
@@ -0,0 +1,21 @@
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<div id="r_queryBuilder">
+    <div class="fontLoader">
+        <i class="fa fa-refresh fa-spin-custom"></i>
+    </div>
+</div>
diff --git a/dashboardv2/public/js/templates/search/SearchResultLayoutView_tmpl.html b/dashboardv2/public/js/templates/search/SearchResultLayoutView_tmpl.html
index 91f1a67..fc2fe8c 100644
--- a/dashboardv2/public/js/templates/search/SearchResultLayoutView_tmpl.html
+++ b/dashboardv2/public/js/templates/search/SearchResultLayoutView_tmpl.html
@@ -20,6 +20,21 @@
     <div class="fontLoader">
         <i class="fa fa-refresh fa-spin-custom"></i>
     </div>
+    <div>
+        <div id="r_searchQuery">
+            <div class="panel panel-default" id="filterPanel">
+                <div class="panel-heading clearfix">
+                    <h4 class="panel-title pull-left">Type,Tag filter/s</h4>
+                    <div class="btn-group pull-right">
+                        <button type="button" id="expand_collapse_panel" class="expand_collapse_panel" title="Collapse"><i class="fa fa-chevron-up" aria-hidden="true"></i></button>
+                    </div>
+                </div>
+                <div id="panel_body" class="panel-body collapse in" align="center">
+                    <p class="filterQuery" id="filterQuery"></p>
+                </div>
+            </div>
+        </div>
+    </div>
     <div class="ellipsis" style="display: none;"><span class="searchResult" style=" font-size: 16px;"></span>
         <a href="javascript:void(0)" class="inputAssignTag multiSelectTerm btnAssign" style="display:none" data-id="addTerm"><i class="fa fa-folder-o"></i> Assign Term</a>
         <a href="javascript:void(0)" class="inputAssignTag multiSelectTag assignTag btnAssign" style="display:none" data-id="addAssignTag"><i class="fa fa-plus"></i> Assign Tag</a>
diff --git a/dashboardv2/public/js/templates/tag/AddTagAttributeView_tmpl.html b/dashboardv2/public/js/templates/tag/AddTagAttributeView_tmpl.html
index a7f9146..26d283b 100644
--- a/dashboardv2/public/js/templates/tag/AddTagAttributeView_tmpl.html
+++ b/dashboardv2/public/js/templates/tag/AddTagAttributeView_tmpl.html
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
 -->
-<div class="fontLoader" style="margin-top:-10px">
+<div class="fontLoader">
     <i class="fa fa-refresh fa-spin-custom"></i>
 </div>
 <div class="row row-margin-bottom hide">
diff --git a/dashboardv2/public/js/templates/tag/createTagLayoutView_tmpl.html b/dashboardv2/public/js/templates/tag/createTagLayoutView_tmpl.html
index 0491c78..8b0b63d 100644
--- a/dashboardv2/public/js/templates/tag/createTagLayoutView_tmpl.html
+++ b/dashboardv2/public/js/templates/tag/createTagLayoutView_tmpl.html
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
 -->
-<div class="fontLoader" style="margin-top:-10px">
+<div class="fontLoader">
     <i class="fa fa-refresh fa-spin-custom"></i>
 </div>
 <form name="tagDefinitionform" class="css-form hide" data-id="createTagForm">
diff --git a/dashboardv2/public/js/utils/Overrides.js b/dashboardv2/public/js/utils/Overrides.js
index b6fc17c..615e3b1 100644
--- a/dashboardv2/public/js/utils/Overrides.js
+++ b/dashboardv2/public/js/utils/Overrides.js
@@ -49,7 +49,6 @@
             }
         }
     });
-
     // For placeholder support 
     if (!('placeholder' in HTMLInputElement.prototype)) {
         var originalRender = Backbone.Marionette.LayoutView.prototype.render;
@@ -141,4 +140,8 @@
             return this;
         }
     });
+
+    String.prototype.capitalize = function() {
+        return this.charAt(0).toUpperCase() + this.slice(1);
+    }
 });
diff --git a/dashboardv2/public/js/utils/UrlLinks.js b/dashboardv2/public/js/utils/UrlLinks.js
index c692d8d..df20cf1 100644
--- a/dashboardv2/public/js/utils/UrlLinks.js
+++ b/dashboardv2/public/js/utils/UrlLinks.js
@@ -28,6 +28,23 @@
                 def: this.baseUrlV2 + '/types/typedef'
             };
         },
+        entitiesDefApiUrl: function(name) {
+            return this.getDefApiUrl('entity', name);
+        },
+        classificationDefApiUrl: function(name) {
+            return this.getDefApiUrl('classification', name);
+        },
+        enumDefApiUrl: function(name) {
+            return this.getDefApiUrl('enum', name);
+        },
+        getDefApiUrl: function(type, name) {
+            var defApiUrl = this.typedefsUrl();
+            if (name) {
+                return defApiUrl.def + '/name/' + name + '?type=' + type;
+            } else {
+                return defApiUrl.defs + '?type=' + type;
+            }
+        },
         taxonomiesApiUrl: function() {
             return this.baseUrl + '/v1/taxonomies';
         },
@@ -44,22 +61,6 @@
                 return entitiesUrl;
             }
         },
-        entitiesDefApiUrl: function(name) {
-            var entitieDefUrl = this.typedefsUrl();
-            if (name) {
-                return entitieDefUrl.def + '/name/' + name + '?type=entity';
-            } else {
-                return entitieDefUrl.defs + '?type=entity';
-            }
-        },
-        enumDefApiUrl: function(name) {
-            var enumDefApiUrl = this.typedefsUrl();
-            if (name) {
-                return enumDefApiUrl.def + '/name/' + name + '?type=enum';
-            } else {
-                return enumDefApiUrl.defs + '?type=enum';
-            }
-        },
         entitiesTraitsApiUrl: function(token) {
             if (token) {
                 return this.baseUrlV2 + '/entity/guid/' + token + '/classifications';
@@ -67,19 +68,16 @@
                 // For Multiple Assignment
                 return this.baseUrlV2 + '/entity/bulk/classification';
             }
-
         },
         entityCollectionaudit: function(guid) {
             return this.baseUrl + '/entities/' + guid + '/audit';
         },
-        typesClassicationApiUrl: function(name, guid) {
+        classicationApiUrl: function(name, guid) {
             var typeUrl = this.typedefsUrl();
             if (name) {
                 return typeUrl.def + '/name/' + name + '?type=classification';
             } else if (guid) {
                 return typeUrl.def + '/guid/' + guid + '?type=classification';
-            } else {
-                return typeUrl.defs + '?type=classification';
             }
         },
         typesApiUrl: function() {
diff --git a/dashboardv2/public/js/utils/Utils.js b/dashboardv2/public/js/utils/Utils.js
index 1d614a8..9071df3 100644
--- a/dashboardv2/public/js/utils/Utils.js
+++ b/dashboardv2/public/js/utils/Utils.js
@@ -166,37 +166,11 @@
             });
         }
     };
-    Utils.localStorage = {
-        checkLocalStorage: function(key, value) {
-            if (typeof(Storage) !== "undefined") {
-                return this.getLocalStorage(key, value);
-            } else {
-                console.log('Sorry! No Web Storage support');
-                Utils.cookie.checkCookie(key, value);
-            }
-        },
-        setLocalStorage: function(key, value) {
-            localStorage.setItem(key, value);
-            return { found: false, 'value': value };
-        },
-        getLocalStorage: function(key, value) {
-            var keyValue = localStorage.getItem(key);
-            if (!keyValue || keyValue == "undefined") {
-                return this.setLocalStorage(key, value);
-            } else {
-                return { found: true, 'value': keyValue };
-            }
-        }
-    };
     Utils.cookie = {
-        setCookie: function(cname, cvalue) {
-            //var d = new Date();
-            //d.setTime(d.getTime() + (exdays*24*60*60*1000));
-            //var expires = "expires=" + d.toGMTString();
+        setValue: function(cname, cvalue) {
             document.cookie = cname + "=" + cvalue + "; ";
-            return { found: false, 'value': cvalue };
         },
-        getCookie: function(findString) {
+        getValue: function(findString) {
             var search = findString + "=";
             var ca = document.cookie.split(';');
             for (var i = 0; i < ca.length; i++) {
@@ -207,16 +181,34 @@
                 }
             }
             return "";
-        },
-        checkCookie: function(key, value) {
-            var findString = getCookie(key);
-            if (findString != "" || keyValue != "undefined") {
-                return { found: true, 'value': ((findString == "undefined") ? (undefined) : (findString)) };
-            } else {
-                return setCookie(key, value);
-            }
         }
     };
+    Utils.localStorage = function() {
+        this.setValue = function() {
+            localStorage.setItem(arguments[0], arguments[1]);
+        }
+        this.getValue = function(key, value) {
+            var keyValue = localStorage.getItem(key);
+            if ((!keyValue || keyValue == "undefined") && (value != undefined)) {
+                return this.setLocalStorage(key, value);
+            } else {
+                if (keyValue === "" || keyValue === "undefined" || keyValue === "null") {
+                    return null;
+                } else {
+                    return keyValue;
+                }
+
+            }
+        }
+        this.removeValue = function() {
+            localStorage.removeItem(arguments[0]);
+        }
+        if (typeof(Storage) === "undefined") {
+            _.extend(this, Utils.cookie);
+            console.log('Sorry! No Web Storage support');
+        }
+    }
+    Utils.localStorage = new Utils.localStorage();
 
     Utils.setUrl = function(options) {
         if (options) {
@@ -509,16 +501,16 @@
     }
     $('body').on('click', '.expand_collapse_panel', function() {
         var icon = $(this).find('i'),
-            panel = $(this).parents('.panel'),
+            panel = $(this).parents('.panel').first(),
             panelBody = panel.find('.panel-body');
         icon.toggleClass('fa-chevron-up fa-chevron-down');
         $(this).toggleAttribute('title', 'Collapse', 'Expand');
-        panelBody.toggle('0.5', 'linear');
+        panelBody.toggle();
         $(this).trigger('expand_collapse_panel', [$(this).parents('.panel')]);
     });
     $('body').on('click', '.fullscreen_panel', function() {
         var icon = $(this).find('i'),
-            panel = $(this).parents('.panel'),
+            panel = $(this).parents('.panel').first(),
             panelBody = panel.find('.panel-body');
         icon.toggleClass('fa-expand fa-compress');
         $(this).toggleAttribute('title', 'Fullscreen', 'Exit Fullscreen');
diff --git a/dashboardv2/public/js/views/business_catalog/SideNavLayoutView.js b/dashboardv2/public/js/views/business_catalog/SideNavLayoutView.js
index af18540..013c72e 100644
--- a/dashboardv2/public/js/views/business_catalog/SideNavLayoutView.js
+++ b/dashboardv2/public/js/views/business_catalog/SideNavLayoutView.js
@@ -66,7 +66,7 @@
             return events;
         },
         initialize: function(options) {
-            _.extend(this, _.pick(options, 'url', 'value', 'tag', 'selectFirst', 'collection', 'typeHeaders', 'searchVent'));
+            _.extend(this, _.pick(options, 'url', 'value', 'tag', 'selectFirst', 'classificationDefCollection', 'typeHeaders', 'searchVent', 'entityDefCollection', 'enumDefCollection', 'filterObj'));
             if (Globals.taxonomy) {
                 this.tabClass = "tab col-sm-4";
             } else {
@@ -94,7 +94,7 @@
             var that = this;
             require(['views/tag/TagLayoutView'], function(TagLayoutView) {
                 that.RTagLayoutView.show(new TagLayoutView({
-                    collection: that.collection,
+                    collection: that.classificationDefCollection,
                     tag: that.tag,
                     typeHeaders: that.typeHeaders
                 }));
@@ -105,8 +105,12 @@
             require(['views/search/SearchLayoutView'], function(SearchLayoutView) {
                 that.RSearchLayoutView.show(new SearchLayoutView({
                     value: that.value,
+                    filterObj: that.filterObj,
                     searchVent: that.searchVent,
-                    typeHeaders: that.typeHeaders
+                    typeHeaders: that.typeHeaders,
+                    entityDefCollection: that.entityDefCollection,
+                    enumDefCollection: that.enumDefCollection,
+                    classificationDefCollection: that.classificationDefCollection
                 }));
             });
         },
diff --git a/dashboardv2/public/js/views/entity/CreateEntityLayoutView.js b/dashboardv2/public/js/views/entity/CreateEntityLayoutView.js
index 704062f..d461d09 100644
--- a/dashboardv2/public/js/views/entity/CreateEntityLayoutView.js
+++ b/dashboardv2/public/js/views/entity/CreateEntityLayoutView.js
@@ -25,13 +25,13 @@
     'models/VEntity',
     'modules/Modal',
     'utils/Messages',
-    'datetimepicker',
     'moment',
     'utils/UrlLinks',
     'collection/VSearchList',
     'utils/Enums',
-    'utils/Globals'
-], function(require, Backbone, CreateEntityLayoutViewTmpl, Utils, VTagList, VEntityList, VEntity, Modal, Messages, datepicker, moment, UrlLinks, VSearchList, Enums, Globals) {
+    'utils/Globals',
+    'daterangepicker'
+], function(require, Backbone, CreateEntityLayoutViewTmpl, Utils, VTagList, VEntityList, VEntity, Modal, Messages, moment, UrlLinks, VSearchList, Enums, Globals) {
 
     var CreateEntityLayoutView = Backbone.Marionette.LayoutView.extend(
         /** @lends CreateEntityLayoutView */
@@ -145,7 +145,7 @@
                     }
                 });
 
-                this.ui.entityInputData.on('keyup change dp.change', 'input.true,select.true', function(e) {
+                this.ui.entityInputData.on('keyup change', 'input.true,select.true', function(e) {
                     if (this.value !== "") {
                         if ($(this).data('select2')) {
                             $(this).data('select2').$container.find('.select2-selection').removeClass("errorClass");
@@ -171,7 +171,7 @@
             },
             bindNonRequiredField: function() {
                 var that = this;
-                this.ui.entityInputData.off('keyup change dp.change', 'input.false,select.false').on('keyup change dp.change', 'input.false,select.false', function(e) {
+                this.ui.entityInputData.off('keyup change', 'input.false,select.false').on('keyup change', 'input.false,select.false', function(e) {
                     if (that.modal.$el.find('button.ok').prop('disabled') && that.ui.entityInputData.find('.errorClass').length === 0) {
                         that.modal.$el.find('button.ok').prop("disabled", false);
                     }
@@ -331,11 +331,12 @@
             initilizeElements: function() {
                 var that = this;
                 this.$('input[data-type="date"]').each(function() {
-                    if (!$(this).data('datepicker')) {
-                        $(this).datetimepicker({
-                            format: 'DD MMMM YYYY',
-                            keepInvalid: true
-                        });
+                    if (!$(this).data('daterangepicker')) {
+                        var dateObj = { "singleDatePicker": true, "showDropdowns": true };
+                        if (that.guid) {
+                            dateObj["startDate"] = this.value
+                        }
+                        $(this).daterangepicker(dateObj);
                     }
                 });
                 this.initializeValidation();
@@ -387,9 +388,9 @@
                     removeText(e, e.currentTarget.value);
                 });
 
-                this.$('input[data-type="date"]').on('dp.hide keydown', function(event) {
+                this.$('input[data-type="date"]').on('hide.daterangepicker keydown', function(event) {
                     if (event.type) {
-                        if (event.type == 'dp') {
+                        if (event.type == 'hide') {
                             this.blur();
                         } else if (event.type == 'keydown') {
                             return false;
@@ -462,7 +463,7 @@
                             entityValue = dataValue;
                         }
                         if (value.typeName === "date" && dataValue) {
-                            entityValue = moment(dataValue).format("DD MMMM YYYY");
+                            entityValue = moment(dataValue).format("MM/DD/YYYY");
                         }
                     }
                 }
@@ -538,7 +539,7 @@
                         if (dataTypeEnitity && datakeyEntity) {
                             if (that.entityDefCollection.fullCollection.find({ name: dataTypeEnitity })) {
                                 entity[datakeyEntity] = extractValue(value, typeName);
-                            } else if (typeof dataTypeEnitity === 'string' && datakeyEntity.indexOf("Time") > -1) {
+                            } else if (dataTypeEnitity === 'date' || dataTypeEnitity === 'time') {
                                 entity[datakeyEntity] = Date.parse(value);
                             } else if (dataTypeEnitity.indexOf("map") > -1 || (typeNameCategory && typeNameCategory.get('category') === 'STRUCT')) {
                                 try {
diff --git a/dashboardv2/public/js/views/search/QueryBuilderView.js b/dashboardv2/public/js/views/search/QueryBuilderView.js
new file mode 100644
index 0000000..468a2d7
--- /dev/null
+++ b/dashboardv2/public/js/views/search/QueryBuilderView.js
@@ -0,0 +1,181 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+define(['require',
+    'backbone',
+    'hbs!tmpl/search/QueryBuilder_tmpl',
+    'utils/Utils',
+    'query-builder',
+    'daterangepicker'
+], function(require, Backbone, QueryBuilder_Tmpl, Utils) {
+
+    var QueryBuilderView = Backbone.Marionette.LayoutView.extend(
+        /** @lends QueryBuilderView */
+        {
+            _viewName: 'QueryBuilderView',
+
+            template: QueryBuilder_Tmpl,
+
+
+
+            /** Layout sub regions */
+            regions: {},
+
+
+            /** ui selector cache */
+            ui: {
+                "builder": "#builder"
+            },
+            /** ui events hash */
+            events: function() {
+                var events = {};
+                return events;
+            },
+            /**
+             * intialize a new QueryBuilderView Layout
+             * @constructs
+             */
+            initialize: function(options) {
+                _.extend(this, _.pick(options, 'attrObj', 'value', 'typeHeaders', 'filterObj', 'entityDefCollection', 'enumDefCollection', 'tag'));
+                this.attrObj = _.sortBy(this.attrObj, 'name');
+            },
+            bindEvents: function() {},
+            getOperator: function(type) {
+                var obj = {
+                    operators: null
+                }
+                if (type === "string") {
+                    obj.operators = ['=', '!=', 'contains', 'begins_with', 'ends_with'];
+                }
+                if (type === "enum" || type === "date" || type === "int" || type === "byte" || type === "short" || type === "long" || type === "float" || type === "double") {
+                    obj.operators = ['=', '!=', '>', '<', '>=', '<='];
+                }
+                return obj;
+            },
+            isPrimitive: function(type) {
+                if (type === "int" || type === "byte" || type === "short" || type === "long" || type === "float" || type === "double" || type === "string" || type === "boolean" || type === "date") {
+                    return true;
+                }
+                return false;
+            },
+            getObjDef: function(attrObj, rules) {
+                var obj = {
+                    id: attrObj.name,
+                    label: attrObj.name.capitalize(),
+                    type: attrObj.typeName
+                };
+                if (obj.type === "date") {
+                    obj['plugin'] = 'daterangepicker';
+                    obj['plugin_config'] = {
+                        "singleDatePicker": true,
+                        "showDropdowns": true,
+                        "timePicker": true,
+                        locale: {
+                            format: 'MM/DD/YYYY h:mm A'
+                        }
+                    };
+                    if (rules && rules.rules) {
+                        var valueObj = _.find(rules.rules, { id: obj.id });
+                        if (valueObj) {
+                            obj.plugin_config["startDate"] = valueObj.value;
+                        }
+                    }
+                    _.extend(obj, this.getOperator(obj.type));
+                    return obj;
+                }
+                if (this.isPrimitive(obj.type)) {
+                    if (obj.type === "long" || obj.type === "float") {
+                        obj.type = "double";
+                    }
+                    if (obj.type === "int" || obj.type === "byte" || obj.type === "short") {
+                        obj.type = "integer";
+                    }
+                    if (obj.type === "boolean") {
+                        obj['input'] = 'select';
+                        obj['values'] = ['true', 'false'];
+                    }
+                    _.extend(obj, this.getOperator(obj.type));
+                    return obj;
+                }
+                var enumObj = this.enumDefCollection.fullCollection.find({ name: obj.type });
+                if (enumObj) {
+                    obj.type = "string";
+                    obj['input'] = 'select';
+                    var value = [];
+                    _.each(enumObj.get('elementDefs'), function(o) {
+                        value.push(o.value)
+                    })
+                    obj['values'] = value;
+                    _.extend(obj, this.getOperator('enum'));
+                    return obj;
+                }
+            },
+            onRender: function() {
+                var that = this,
+                    filters = [];
+                if (this.filterObj) {
+                    var filter = this.filterObj[(this.tag ? 'tagFilters' : 'entityFilters')],
+                        tagTermName = this.tag ? this.value.tag : this.value.type;
+                    if (filter) {
+                        ruleObj = filter[tagTermName];
+                        if (ruleObj) {
+                            var rules_widgets = ruleObj.rule;
+                        }
+                    }
+                }
+
+                _.each(this.attrObj, function(obj) {
+                    var returnObj = that.getObjDef(obj, rules_widgets);
+                    if (returnObj) {
+                        filters.push(returnObj);
+                    }
+                });
+                if (filters && !_.isEmpty(filters)) {
+                    this.ui.builder.queryBuilder({
+                        plugins: ['bt-tooltip-errors'],
+                        filters: filters,
+                        select_placeholder: '--Select Attribute--',
+                        allow_empty: true,
+                        conditions: ['AND'],
+                        allow_groups: false,
+                        allow_empty: true,
+                        operators: [
+                            { type: '=', nb_inputs: 1, multiple: false, apply_to: ['number', 'string', 'boolean'] },
+                            { type: '!=', nb_inputs: 1, multiple: false, apply_to: ['number', 'string', 'boolean'] },
+                            { type: '>', nb_inputs: 1, multiple: false, apply_to: ['number', 'string', 'boolean'] },
+                            { type: '<', nb_inputs: 1, multiple: false, apply_to: ['number', 'string', 'boolean'] },
+                            { type: '>=', nb_inputs: 1, multiple: false, apply_to: ['number', 'string', 'boolean'] },
+                            { type: '<=', nb_inputs: 1, multiple: false, apply_to: ['number', 'string', 'boolean'] },
+                            { type: 'contains', nb_inputs: 1, multiple: false, apply_to: ['string'] },
+                            { type: 'begins_with', nb_inputs: 1, multiple: false, apply_to: ['string'] },
+                            { type: 'ends_with', nb_inputs: 1, multiple: false, apply_to: ['string'] }
+                        ],
+                        lang: {
+                            add_rule: 'Add filter',
+                            add_group: 'Add filter group'
+                        },
+                        rules: rules_widgets
+                    });
+                    this.$('.rules-group-header .btn-group.pull-right.group-actions').toggleClass('pull-right pull-left');
+                } else {
+                    this.ui.builder.html('<h4>No Attributes are available !</h4>')
+                }
+            }
+        });
+    return QueryBuilderView;
+});
diff --git a/dashboardv2/public/js/views/search/SearchDetailLayoutView.js b/dashboardv2/public/js/views/search/SearchDetailLayoutView.js
index b22fae8..32ad542 100644
--- a/dashboardv2/public/js/views/search/SearchDetailLayoutView.js
+++ b/dashboardv2/public/js/views/search/SearchDetailLayoutView.js
@@ -43,7 +43,7 @@
              * @constructs
              */
             initialize: function(options) {
-                _.extend(this, _.pick(options, 'value', 'initialView', 'entityDefCollection', 'typeHeaders', 'searchVent', 'enumDefCollection'));
+                _.extend(this, _.pick(options, 'value', 'initialView', 'entityDefCollection', 'typeHeaders', 'searchVent', 'enumDefCollection', 'filterObj'));
             },
             bindEvents: function() {},
             onRender: function() {
@@ -62,6 +62,7 @@
                             entityDefCollection: that.entityDefCollection,
                             typeHeaders: that.typeHeaders,
                             searchVent: that.searchVent,
+                            filterObj: that.filterObj,
                             enumDefCollection: that.enumDefCollection
                         }));
                     }
diff --git a/dashboardv2/public/js/views/search/SearchLayoutView.js b/dashboardv2/public/js/views/search/SearchLayoutView.js
index 32b82d7..7ac394c 100644
--- a/dashboardv2/public/js/views/search/SearchLayoutView.js
+++ b/dashboardv2/public/js/views/search/SearchLayoutView.js
@@ -44,7 +44,9 @@
                 typeLov: '[data-id="typeLOV"]',
                 tagLov: '[data-id="tagLOV"]',
                 refreshBtn: '[data-id="refreshBtn"]',
-                advancedInfoBtn: '[data-id="advancedInfo"]'
+                advancedInfoBtn: '[data-id="advancedInfo"]',
+                typeAttrFilter: '[data-id="typeAttrFilter"]',
+                tagAttrFilter: '[data-id="tagAttrFilter"]'
             },
 
             /** ui events hash */
@@ -65,6 +67,12 @@
                 events["change " + this.ui.tagLov] = 'checkForButtonVisiblity';
                 events["click " + this.ui.refreshBtn] = 'onRefreshButton';
                 events["click " + this.ui.advancedInfoBtn] = 'advancedInfo';
+                events["click " + this.ui.typeAttrFilter] = function() {
+                    this.openAttrFilter('type');
+                };
+                events["click " + this.ui.tagAttrFilter] = function() {
+                    this.openAttrFilter('tag');
+                };
                 return events;
             },
             /**
@@ -72,7 +80,7 @@
              * @constructs
              */
             initialize: function(options) {
-                _.extend(this, _.pick(options, 'value', 'typeHeaders', 'searchVent'));
+                _.extend(this, _.pick(options, 'value', 'typeHeaders', 'searchVent', 'entityDefCollection', 'enumDefCollection', 'classificationDefCollection', 'filterObj'));
                 this.type = "basic";
                 var param = Utils.getUrlState.getQueryParams();
                 this.query = {
@@ -83,9 +91,14 @@
                     basic: {
                         query: null,
                         type: null,
+                        typeFilter: null,
+                        tagFilter: null,
                         tag: null
                     }
                 };
+                if (!this.value) {
+                    this.value = {};
+                }
                 this.dsl = false;
                 if (param && param.searchType) {
                     this.type = param.searchType;
@@ -108,6 +121,51 @@
                     this.checkForButtonVisiblity();
                 }, this);
             },
+            bindSelect2Events: function(argument) {
+                var that = this;
+                this.ui.typeLov.on('select2:select', function(argument) {
+                    // this function calles after checkForButtonVisiblity that is why disabled flter here
+                    that.ui.typeAttrFilter.prop('disabled', false);
+                    _.extend(that.value, { 'type': this.value });
+                    that.makeFilterButtonActive('type');
+                });
+                this.ui.tagLov.on('select2:select', function(argument) {
+                    // this function calles after checkForButtonVisiblity that is why disabled flter here
+                    that.ui.tagAttrFilter.prop('disabled', false);
+                    _.extend(that.value, { 'tag': this.value });
+                    that.makeFilterButtonActive('tag');
+                });
+                this.ui.typeLov.on('select2:unselect', function(argument) {
+                    _.extend(that.value, { 'type': null });
+                });
+                this.ui.tagLov.on('select2:unselect', function(argument) {
+                    _.extend(that.value, { 'tag': null });
+                });
+            },
+            makeFilterButtonActive: function(type) {
+                if (this.filterObj) {
+                    var tagFilters = this.filterObj.tagFilters,
+                        entityFilters = this.filterObj.entityFilters;
+                    if (type == "type") {
+                        if (_.has(entityFilters, this.value[type])) {
+                            this.query[this.type]['entityFilters'] = +new Date();
+                            this.ui.typeAttrFilter.addClass('active');
+                        } else {
+                            this.query[this.type]['entityFilters'] = null;
+                            this.ui.typeAttrFilter.removeClass('active');
+                        }
+                    }
+                    if (type == "tag") {
+                        if (_.has(tagFilters, this.value[type])) {
+                            this.query[this.type]['tagFilters'] = +new Date();
+                            this.ui.tagAttrFilter.addClass('active');
+                        } else {
+                            this.query[this.type]['tagFilters'] = null;
+                            this.ui.tagAttrFilter.removeClass('active');
+                        }
+                    }
+                }
+            },
             checkForButtonVisiblity: function() {
                 var that = this,
                     value = this.ui.searchInput.val() || this.ui.typeLov.val();
@@ -122,6 +180,24 @@
                 } else {
                     this.ui.searchBtn.attr("disabled", "true");
                 }
+                if (this.value) {
+                    if (this.value.tag) {
+                        this.ui.tagAttrFilter.prop('disabled', false);
+                    } else {
+                        this.ui.tagAttrFilter.prop('disabled', true);
+                    }
+                    if (this.value.type) {
+                        this.ui.typeAttrFilter.prop('disabled', false);
+                    } else {
+                        this.ui.typeAttrFilter.prop('disabled', true);
+                    }
+                    this.makeFilterButtonActive('type');
+                    this.makeFilterButtonActive('tag');
+                } else {
+                    this.ui.tagAttrFilter.prop('disabled', true);
+                    this.ui.typeAttrFilter.prop('disabled', true);
+                }
+
             },
             onRender: function() {
                 // array of tags which is coming from url
@@ -135,19 +211,24 @@
                     placeholder: "Select",
                     allowClear: true
                 });
-                this.bindEvents();
+                this.bindSelect2Events();
                 this.checkForButtonVisiblity();
             },
             updateQueryObject: function(param) {
                 if (param && param.searchType) {
                     this.type = param.searchType;
                 }
-                _.extend(this.query[this.type], {
+                _.extend(this.query[this.type],
+                    (this.type == "dsl" ? {
+                        query: null,
+                        type: null
+                    } : {
                         query: null,
                         type: null,
-                        tag: null
-                    },
-                    param);
+                        tag: null,
+                        entityFilters: null,
+                        tagFilters: null
+                    }), param);
             },
             fetchCollection: function(value) {
                 this.typeHeaders.fetch({ reset: true });
@@ -176,6 +257,86 @@
                     });
                 });
             },
+            openAttrFilter: function(filterType) {
+                var that = this;
+                require(['views/search/SearchQueryView'], function(SearchQueryView) {
+                    that.attrModal = new SearchQueryView({
+                        value: that.value,
+                        tag: (filterType === "tag" ? true : false),
+                        type: (filterType === "type" ? true : false),
+                        searchVent: that.searchVent,
+                        typeHeaders: that.typeHeaders,
+                        entityDefCollection: that.entityDefCollection,
+                        enumDefCollection: that.enumDefCollection,
+                        filterObj: that.filterObj,
+                        classificationDefCollection: that.classificationDefCollection
+                    });
+                    that.attrModal.on('ok', function(e) {
+                        that.okAttrFilterButton();
+                    });
+                });
+            },
+            okAttrFilterButton: function() {
+                var filtertype = this.attrModal.tag ? 'tagFilters' : 'entityFilters',
+                    rule = this.attrModal.RQueryBuilder.currentView.ui.builder.queryBuilder('getRules'),
+                    result = this.getQueryBuilderParsData(rule);
+                if (result && !_.isEmpty(result.criterion)) {
+                    this.query[this.type][filtertype] = +new Date();
+                    if (result) {
+                        var filterObj = this.filterObj ? this.filterObj[filtertype] : null;
+                        if (!filterObj) {
+                            filterObj = {};
+                        }
+                        var temp = {}; // IE fix
+                        temp[(this.attrModal.tag ? this.value.tag : this.value.type)] = { 'result': result, 'rule': rule };
+                        _.extend(filterObj, temp);
+                        this.filterObj[filtertype] = filterObj;
+                        this.makeFilterButtonActive(this.attrModal.tag ? 'tag' : 'type');
+                        Utils.localStorage.setValue((filtertype), JSON.stringify(filterObj));
+                    } else {
+                        this.filterObj[filtertype] = null;
+                        this.query[this.type][filtertype] = null;
+                        this.makeFilterButtonActive(this.attrModal.tag ? 'tag' : 'type');
+                        Utils.localStorage.removeValue(filtertype);
+                    }
+                } else {
+                    this.filterObj[filtertype] = null;
+                    this.query[this.type][filtertype] = null;
+                    this.makeFilterButtonActive(this.attrModal.tag ? 'tag' : 'type');
+                    Utils.localStorage.removeValue(filtertype);
+                }
+                this.attrModal.modal.close();
+            },
+            getQueryBuilderParsData: function(obj) {
+                if (obj) {
+                    var parsObj = {
+                        "condition": obj.condition,
+                        "criterion": convertKeyAndExtractObj(obj.rules)
+                    }
+                }
+
+                function convertKeyAndExtractObj(rules) {
+                    var convertObj = [];
+                    _.each(rules, function(rulObj) {
+                        var tempObj = {}
+                        if (rulObj.rules) {
+                            tempObj = {
+                                "condition": rulObj.condition,
+                                "criterion": convertKeyAndExtractObj(rulObj.rules)
+                            }
+                        } else {
+                            tempObj = {
+                                "attributeName": rulObj.id,
+                                "operator": rulObj.operator,
+                                "attributeValue": (rulObj.type === "date" ? Date.parse(rulObj.value) : rulObj.value)
+                            }
+                        }
+                        convertObj.push(tempObj);
+                    });
+                    return convertObj;
+                }
+                return parsObj;
+            },
             manualRender: function(paramObj) {
                 this.updateQueryObject(paramObj);
                 this.setValues(paramObj);
@@ -232,6 +393,7 @@
                     setTimeout(function() {
                         that.ui.searchInput.focus();
                     }, 0);
+                    //this.searchVent.trigger('searchAttribute', this.value);
                 }
             },
             findSearchResult: function() {
@@ -243,7 +405,6 @@
                 if (!this.dsl) {
                     this.query[this.type].tag = this.ui.tagLov.select2('val') || null;
                 }
-
                 Utils.setUrl({
                     url: '#!/search/searchResult',
                     urlParams: _.extend(this.query[this.type], {
@@ -263,7 +424,11 @@
                     this.type = "dsl";
                     this.dsl = true;
                     this.$('.tagBox').hide();
+                    this.$('.temFilterBtn').hide();
+                    this.$('.temFilter').toggleClass('col-sm-10 col-sm-12');
                 } else {
+                    this.$('.temFilter').toggleClass('col-sm-10 col-sm-12');
+                    this.$('.temFilterBtn').show();
                     this.$('.tagBox').show();
                     this.dsl = false;
                     this.type = "basic";
diff --git a/dashboardv2/public/js/views/search/SearchQueryView.js b/dashboardv2/public/js/views/search/SearchQueryView.js
new file mode 100644
index 0000000..37ccf90
--- /dev/null
+++ b/dashboardv2/public/js/views/search/SearchQueryView.js
@@ -0,0 +1,113 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+define(['require',
+    'backbone',
+    'modules/Modal',
+    'utils/Utils',
+    'hbs!tmpl/search/SearchQuery_tmpl',
+], function(require, Backbone, Modal, Utils, SearchQuery_Tmpl) {
+
+    var SearchQueryView = Backbone.Marionette.LayoutView.extend(
+        /** @lends SearchQueryView */
+        {
+            _viewName: 'SearchQueryView',
+
+            template: SearchQuery_Tmpl,
+
+
+
+            /** Layout sub regions */
+            regions: {
+                RQueryBuilder: '#r_queryBuilder',
+            },
+
+
+            /** ui selector cache */
+            ui: {},
+            /** ui events hash */
+            events: function() {
+                var events = {};
+                return events;
+            },
+            /**
+             * intialize a new SearchQueryView Layout
+             * @constructs
+             */
+            initialize: function(options) {
+                _.extend(this, _.pick(options, 'value', 'entityDefCollection', 'typeHeaders', 'searchVent', 'enumDefCollection', 'classificationDefCollection', 'tag', 'filterObj'));
+                this.bindEvents();
+                var that = this;
+                this.modal = new Modal({
+                    title: 'Attribute Filter',
+                    content: this,
+                    okText: 'Apply',
+                    cancelText: "Cancel",
+                    allowCancel: true,
+                    okCloses: false,
+                    width: '50%'
+                }).open();
+                this.modal.on('closeModal', function() {
+                    that.modal.trigger('cancel');
+                });
+            },
+            onRender: function() {
+                this.$('.fontLoader').show();
+                var obj = {
+                    value: this.value,
+                    searchVent: this.searchVent,
+                    entityDefCollection: this.entityDefCollection,
+                    enumDefCollection: this.enumDefCollection,
+                    filterObj: this.filterObj,
+                    classificationDefCollection: this.classificationDefCollection
+                }
+
+                if (this.tag) {
+                    obj['tag'] = true;
+                    obj['attrObj'] = this.classificationDefCollection.fullCollection.find({ name: this.value.tag });
+                    if (obj.attrObj) {
+                        obj.attrObj = Utils.getNestedSuperTypeObj({
+                            data: obj.attrObj.toJSON(),
+                            collection: this.classificationDefCollection,
+                            attrMerge: true,
+                        });
+                    }
+                } else {
+                    obj['type'] = true;
+                    obj['attrObj'] = this.entityDefCollection.fullCollection.find({ name: this.value.type });
+                    if (obj.attrObj) {
+                        obj.attrObj = Utils.getNestedSuperTypeObj({
+                            data: obj.attrObj.toJSON(),
+                            collection: this.entityDefCollection,
+                            attrMerge: true
+                        });
+                    }
+                }
+                this.renderQueryBuilder(obj);
+                // this.showHideFilter(this.value);
+            },
+            bindEvents: function() {},
+            renderQueryBuilder: function(obj) {
+                var that = this;
+                require(['views/search/QueryBuilderView'], function(QueryBuilderView) {
+                    that.RQueryBuilder.show(new QueryBuilderView(obj));
+                });
+            }
+        });
+    return SearchQueryView;
+});
diff --git a/dashboardv2/public/js/views/search/SearchResultLayoutView.js b/dashboardv2/public/js/views/search/SearchResultLayoutView.js
index 1198809..5236751 100644
--- a/dashboardv2/public/js/views/search/SearchResultLayoutView.js
+++ b/dashboardv2/public/js/views/search/SearchResultLayoutView.js
@@ -44,6 +44,7 @@
                 RTagLayoutView: "#r_tagLayoutView",
                 RSearchLayoutView: "#r_searchLayoutView",
                 REntityTableLayoutView: "#r_searchResultTableLayoutView",
+                RSearchQuery: '#r_searchQuery'
             },
 
             /** ui selector cache */
@@ -61,7 +62,9 @@
                 editEntityButton: "[data-id='editEntityButton']",
                 createEntity: "[data-id='createEntity']",
                 checkDeletedEntity: "[data-id='checkDeletedEntity']",
-                containerCheckBox: "[data-id='containerCheckBox']"
+                containerCheckBox: "[data-id='containerCheckBox']",
+                filterPanel: "#filterPanel",
+                filterQuery: "#filterQuery"
             },
             templateHelpers: function() {
                 return {
@@ -126,7 +129,7 @@
              * @constructs
              */
             initialize: function(options) {
-                _.extend(this, _.pick(options, 'value', 'initialView', 'entityDefCollection', 'typeHeaders', 'searchVent', 'enumDefCollection', 'tagCollection'));
+                _.extend(this, _.pick(options, 'value', 'initialView', 'entityDefCollection', 'typeHeaders', 'searchVent', 'enumDefCollection', 'tagCollection', 'filterObj'));
                 var pagination = "";
                 this.entityModel = new VEntity();
                 this.searchCollection = new VSearchList();
@@ -198,7 +201,7 @@
                     } else {
                         if (response.statusText !== "abort") {
                             Utils.notifyError({
-                                content: "Invalid Expression : " + model.queryParams.query
+                                content: "Invalid Expression"
                             });
                         }
                     }
@@ -206,6 +209,9 @@
                 this.listenTo(this.searchVent, "search:refresh", function(model, response) {
                     this.fetchCollection();
                 }, this);
+                this.listenTo(this.searchVent, "searchAttribute", function(obj) {
+                    this.showHideFilter(obj);
+                }, this);
             },
             onRender: function() {
                 if (!this.initialView) {
@@ -234,27 +240,74 @@
                         this.$(".entityLink").show();
                     }
                 }
+                this.showHideFilter();
+            },
+            generateQueryOfFilter: function() {
+                var value = this.value,
+                    entityFilters = this.filterObj && this.filterObj.entityFilters ? this.filterObj.entityFilters[value.type] : null,
+                    tagFilters = this.filterObj && this.filterObj.tagFilters ? this.filterObj.tagFilters[value.tag] : null,
+                    queryArray = [],
+                    objToString = function(filterObj) {
+                        var tempObj = [];
+                        _.each(filterObj.rules, function(obj) {
+                            tempObj.push('<span class="key">' + obj.field + '</span>&nbsp<span class="operator">' + obj.operator + '</span>&nbsp<span class="value">' + obj.value + "</span>")
+                        });
+                        return tempObj.join('&nbsp<span class="operator">AND</span>&nbsp');
+                    }
+                if (entityFilters) {
+                    var typeKeyValue = '<span class="key">Type:</span>&nbsp<span class="value">' + value.type + '</span>&nbsp<span class="operator">AND</span>&nbsp';
+                    queryArray = queryArray.concat(typeKeyValue + objToString(entityFilters.rule));
+                }
+                if (tagFilters) {
+                    var tagKeyValue = '<span class="key">Tag:</span>&nbsp<span class="value">' + value.tag + '</span>&nbsp<span class="operator">AND</span>&nbsp';
+                    queryArray = queryArray.concat(tagKeyValue + objToString(tagFilters.rule));
+
+                }
+                if (queryArray.length == 2) {
+                    return "<span>(</span>&nbsp" + queryArray.join('<span>&nbsp)</span>&nbsp<span>AND</span>&nbsp<span>(</span>&nbsp') + "&nbsp<span>)</span>";
+                } else {
+                    return queryArray.join();
+                }
+            },
+            showHideFilter: function() {
+                if (this.value) {
+                    if (Utils.getUrlState.isSearchTab() && this.value.searchType == "basic") {
+                        var query = this.generateQueryOfFilter();
+                        if (query) {
+                            this.ui.filterQuery.html(query);
+                            this.ui.filterPanel.show();
+                        } else
+                            this.ui.filterPanel.hide();
+                    } else {
+                        this.ui.filterPanel.hide();
+                    }
+                } else {
+                    this.ui.filterPanel.hide();
+                }
             },
             fetchCollection: function(value, clickObj) {
-                var that = this;
+                var that = this,
+                    isPostMethod = this.value.searchType === "basic" && Utils.getUrlState.isSearchTab(),
+                    tagFilters = this.filterObj && this.filterObj.tagFilters ? this.filterObj.tagFilters[this.value.tag] : null,
+                    entityFilters = this.filterObj && this.filterObj.entityFilters ? this.filterObj.entityFilters[this.value.type] : null,
+                    filterObj = {
+                        'entityFilters': entityFilters ? entityFilters.result : null,
+                        'tagFilters': tagFilters ? tagFilters.result : null
+                    }
                 this.showLoader();
                 if (Globals.searchApiCallRef && Globals.searchApiCallRef.readyState === 1) {
                     Globals.searchApiCallRef.abort();
                 }
-                if (value) {
-                    $.extend(this.searchCollection.queryParams, { limit: this.limit, excludeDeletedEntities: true });
-                    if (value.searchType) {
-                        this.searchCollection.url = UrlLinks.searchApiUrl(value.searchType);
-                    }
-                    _.extend(this.searchCollection.queryParams, { 'query': (value.query ? value.query.trim() : null), 'typeName': value.type || null, 'classification': value.tag || null });
-                }
-                Globals.searchApiCallRef = this.searchCollection.fetch({
+                var apiObj = {
                     skipDefaultError: true,
-                    success: function() {
+                    success: function(model, response) {
                         Globals.searchApiCallRef = undefined;
                         if (!(that.ui.pageRecordText instanceof jQuery)) {
                             return;
                         }
+                        if (isPostMethod) {
+                            that.searchCollection.reset(model.entities);
+                        }
                         if (that.searchCollection.models.length === 0 && that.offset > that.limit) {
                             that.ui.nextData.attr('disabled', true);
                             that.offset = that.offset - that.limit;
@@ -302,6 +355,38 @@
                     },
                     silent: true,
                     reset: true
+                }
+                if (value) {
+                    $.extend(this.searchCollection.queryParams, { limit: this.limit, excludeDeletedEntities: true });
+                    if (value.searchType) {
+                        this.searchCollection.url = UrlLinks.searchApiUrl(value.searchType);
+                    }
+                    _.extend(this.searchCollection.queryParams, { 'query': (value.query ? value.query.trim() : null), 'typeName': value.type || null, 'classification': value.tag || null });
+                    if (isPostMethod) {
+                        apiObj['data'] = _.extend({}, filterObj, _.pick(this.searchCollection.queryParams, 'query', 'excludeDeletedEntities', 'limit', 'offset', 'typeName', 'classification'))
+                        Globals.searchApiCallRef = this.searchCollection.getBasicRearchResult(apiObj);
+                        this.showHideFilter();
+                    } else {
+                        apiObj.data = null;
+                        Globals.searchApiCallRef = this.searchCollection.fetch(apiObj);
+                    }
+                } else {
+                    if (isPostMethod) {
+                        apiObj['data'] = _.extend({}, filterObj, _.pick(this.searchCollection.queryParams, 'query', 'excludeDeletedEntities', 'limit', 'offset', 'typeName', 'classification'));
+                        Globals.searchApiCallRef = this.searchCollection.getBasicRearchResult(apiObj);
+                    } else {
+                        apiObj.data = null;
+                        Globals.searchApiCallRef = this.searchCollection.fetch(apiObj);
+                    }
+                }
+            },
+            renderSearchQueryView: function() {
+                var that = this;
+                require(['views/search/SearchQueryView'], function(SearchQueryView) {
+                    that.RSearchQuery.show(new SearchQueryView({
+                        value: that.value,
+                        searchVent: that.searchVent
+                    }));
                 });
             },
             renderTableLayoutView: function(col) {
@@ -343,7 +428,7 @@
                     col = {};
                 col['Check'] = {
                     name: "selected",
-                    label: "",
+                    label: "Select",
                     cell: "select-row",
                     headerCell: "select-all"
                 };
diff --git a/dashboardv2/public/js/views/tag/TagDetailLayoutView.js b/dashboardv2/public/js/views/tag/TagDetailLayoutView.js
index 3bb27c3..410c629 100644
--- a/dashboardv2/public/js/views/tag/TagDetailLayoutView.js
+++ b/dashboardv2/public/js/views/tag/TagDetailLayoutView.js
@@ -44,7 +44,8 @@
              * @constructs
              */
             initialize: function(options) {
-                _.extend(this, _.pick(options, 'tag', 'collection', 'entityDefCollection', 'typeHeaders', 'enumDefCollection'));
+                _.extend(this, _.pick(options, 'tag', 'classificationDefCollection', 'entityDefCollection', 'typeHeaders', 'enumDefCollection'));
+                this.collection = this.classificationDefCollection;
             },
             bindEvents: function() {},
             onRender: function() {
diff --git a/dashboardv2/public/js/views/tag/TagLayoutView.js b/dashboardv2/public/js/views/tag/TagLayoutView.js
index a5b5665..b8a1cd1 100644
--- a/dashboardv2/public/js/views/tag/TagLayoutView.js
+++ b/dashboardv2/public/js/views/tag/TagLayoutView.js
@@ -64,7 +64,7 @@
             bindEvents: function() {
                 var that = this;
                 this.listenTo(this.collection, "reset add remove", function() {
-                    this.tagsAndTypeGenerator('collection');
+                    this.tagsGenerator();
                 }, this);
                 this.ui.tagsParent.on('click', 'li.parent-node a', function() {
                     that.setUrl(this.getAttribute("href"));
@@ -147,7 +147,7 @@
                     }
                 }
             },
-            tagsAndTypeGenerator: function(collection, searchString) {
+            tagsGenerator: function(searchString) {
                 var that = this,
                     str = '';
                 that.collection.fullCollection.comparator = function(model) {
@@ -340,7 +340,7 @@
             },
             offlineSearchTag: function(e) {
                 var type = $(e.currentTarget).data('type');
-                this.tagsAndTypeGenerator('collection', $(e.currentTarget).val());
+                this.tagsGenerator($(e.currentTarget).val());
             },
             createTagAction: function() {
                 var that = this;