var app = angular.module('plunker', [
  'datatables'
]);

app.controller('MainCtrl', function($scope) {
  $scope.data = [
      {"name":"dante", "number":"4", "role":"admin"},
      {"name":"erika", "number":"2", "role":"user"},
      {"name":"fritz", "number":"5", "role":"admin"},
      {"name":"gerda", "number":"3", "role":"user"},
      {"name":"hanna", "number":"5", "role":"user"},
      {"name":"ingolf", "number":"2", "role":"user"},
      {"name":"johanna", "number":"4", "role":"admin"},
      {"name":"anke", "number":"2", "role":"user"},
      {"name":"boris", "number":"1", "role":"admin"},
      {"name":"clara", "number":"3", "role":"user"},
      {"name":"diane", "number":"4", "role":"admin"},
      {"name":"emil", "number":"2", "role":"user"},
      {"name":"frauke", "number":"5", "role":"user"},
      {"name":"gabi", "number":"3", "role":"admin"},
      {"name":"heiko", "number":"5", "role":"user"},
      {"name":"inge", "number":"2", "role":"user"},
      {"name":"jana", "number":"4", "role":"user"},
      {"name":"arnold", "number":"2", "role":"user"},
      {"name":"berndt", "number":"1", "role":"user"},
      {"name":"carla", "number":"3", "role":"admin"},
      {"name":"dora", "number":"4", "role":"admin"},
      {"name":"ebert", "number":"2", "role":"user"},
      {"name":"frieda", "number":"5", "role":"admin"},
      {"name":"gerhardt", "number":"3", "role":"admin"},
      {"name":"harald", "number":"5", "role":"user"},
      {"name":"ingrid", "number":"2", "role":"user"},
      {"name":"jürgen", "number":"4", "role":"user"},
      {"name":"arni", "number":"2", "role":"admin"},
      {"name":"berta", "number":"1", "role":"user"},
      {"name":"charles", "number":"3", "role":"user"}
    ];
    
    
    $scope.buttons =[
      {
        classes: 'btn btn-alert',
        content: '<i class="fa fa-edit">del</i>',
        event: function(data, index) {
          $scope.data.splice(index,1);
        }
      },{
        classes: 'btn btn-alert',
        content: '<i class="fa fa-edit">show</i>',
        event: function(data, index) {
          alert(JSON.stringify(data));
        }
      }
    ];
    
    $scope.columns = [
      {
        data: 'name',
        title: 'Name',
        filter: 'text'
      }
    ];
    
    $scope.callback= { bla: function() {
      alert("hallo");
    }
    };
});

app.directive('datatableWrapper', ['DTOptionsBuilder', 'DTColumnBuilder', '$q', '$compile', function(DTOptionsBuilder, DTColumnBuilder, $q, $compile){
  return {
    restrict: 'E',
    scope: {
      data: '=',
      buttonDef: '=',
      columnDef: '='
    },
    controller: function($scope) {
      var buttonCallbacks = [];
      
      if ($scope.buttonDef) {
        if ($scope.buttonDef.constructor === Array) {
          for (var i = 0; i < $scope.buttonDef.length; i++) {
            buttonCallbacks.push($scope.buttonDef[i].event);
          }
        } else {
          buttonCallbacks.push($scope.buttonDef.event);
        }
      }
      
      
      var log = [];
      
      function actionsHtml(data, type, full, meta) {
        
        
        function createButton(buttonDef, buttonIndex, rowIndex) {
          var button = angular.element('<button></button>');
          
          button.addClass(buttonDef.classes);
          button.attr('ng-click', 'rowButtonClicked(' + buttonIndex + ',' + rowIndex + ')');
          button.append(buttonDef.content);
          return button;
        }
        
        var html = angular.element('<div></div>');
        if ($scope.buttonDef.constructor === Array) {
          
          for (var i = 0; i < $scope.buttonDef.length; i++) {
            html.append(createButton($scope.buttonDef[i],i,$scope.data.indexOf(data)));
          }
        } else {
          html.append(createButton($scope.buttonDef,0, $scope.data.indexOf(data)));
        }
        return html.html();
      }
      
      $scope.func = function() {
        alert();
      }
      
      $scope.rowButtonClicked = function(buttonIndex, rowIndex) {
        buttonCallbacks[buttonIndex]($scope.data[rowIndex], rowIndex);
      }
      
      
      var getTableData = function() {
          var deferred = $q.defer();
          deferred.resolve($scope.data);
          return deferred.promise;
      };
      
      $scope.dt = {};
      $scope.dt.instance = null;
      $scope.dt.options = DTOptionsBuilder.fromFnPromise(getTableData);
      $scope.dt.options.withPaginationType('full_numbers');
      $scope.dt.options['buttons'] = [
        {
          extend: 'colvis',
          StateChange: function() {
            alert();
          }
        },
        {
          extend: 'collection',
          text: 'Export',
          buttons: [
            {
              extend: 'csv',
              exportOptions: {
                columns: [1, 2, 3 ]
              }
            }, {
              extend: 'excel',
              exportOptions: {
                columns: [1, 2, 3 ]
              }
            },{
              extend: 'print',
              exportOptions: {
                columns: [1, 2, 3 ]
              }
            }
          ]
        }
      ];
       $scope.dt.options.withOption('createdRow', function(row, data, dataIndex){
         $compile(angular.element(row).contents())($scope);
       });
      $scope.dt.options['dom']= 'Bfrtlip';
      /*$scope.dt.options.withOption('fnRowCallback', function(nRow, aData, iDisplayIndex, iDisplayIndexFull) {
        $('td', nRow).unbind('click');
        $('td', nRow).bind('click', function() {
            $scope.$apply(function() {
                aData.name="test";
                alert(JSON.stringify($scope.data));
            });
        });
        return nRow;
      });*/
      
      
      
      
      
      
      
      $scope.dt.columns = [];
      if(buttonCallbacks.length) {
        $scope.dt.columns.push(DTColumnBuilder.newColumn(null).withTitle('').notSortable().renderWith(actionsHtml));
      }
      $scope.dt.columns.push(DTColumnBuilder.newColumn('name').withTitle('ID'));
      $scope.dt.columns.push(DTColumnBuilder.newColumn('number').withTitle('First name'));
      $scope.dt.columns.push(DTColumnBuilder.newColumn('role').withTitle('Last name'));
      
      
      
      $scope.$watch('dt.instance', function() {
        if ($scope.dt.instance.DataTable) {
          $scope.dt.instance.DataTable.settings()[0].oInstance.selector ='#' + $scope.dt.instance.dataTable.attr('id');
          yadcf.init($scope.dt.instance.DataTable, [
            {
  		        column_number: 0,
              filter_type: "text",
  		        exclude: true,
  		        exclude_label: '!(not)'
  					}, {
  		        column_number: 1,
  		        filter_type: 'range_number_slider'
  			    }, {
  		        column_number: 2,
  		        filter_type: "text",
  		        exclude: true,
  		        exclude_label: '!(not)'
  			    }
		      ]);
		      
		      
		      $scope.dt.instance.DataTable.on( 'column-visibility.dt', function ( e, settings, column, state ) {
            alert(column);
          });
        }
      });
      
      
      
      
        
        
      $scope.$watch('data', function() {
        $scope.dt.instance.reloadData();
      }, true);
      
      $scope.alertFunc = function() {
       alert(JSON.stringify($scope.dt.columns));
			   alert();
			   
      };
    },
    templateUrl: 'template.html'
  };
}]);
<!DOCTYPE html>
<html ng-app="plunker">

  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <link href="style.css" rel="stylesheet" />
    <link href="//cdn.datatables.net/1.10.8/css/jquery.dataTables.min.css" rel="stylesheet" />
    <link href="https://cdn.datatables.net/buttons/1.0.3/css/buttons.dataTables.min.css" rel="stylesheet" />
     
    <script type="text/javascript" src="https://code.jquery.com/jquery-1.11.3.js"></script>
    <script type="text/javascript" src="https://code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
    
    <script type="text/javascript" src="//cdn.datatables.net/1.10.8/js/jquery.dataTables.min.js"></script>
    <script type="text/javascript" data-semver="1.4.3" src="https://code.angularjs.org/1.4.3/angular.js" data-require="angular.js@1.4.x"></script>
    <script type="text/javascript" src="angular-datatables.js"></script>
    <script type="text/javascript" src="https://cdn.datatables.net/buttons/1.0.3/js/dataTables.buttons.min.js"></script>
    <script type="text/javascript" src="https://cdn.datatables.net/buttons/1.0.3/js/buttons.flash.min.js"></script>
    <script type="text/javascript" src="https://cdn.datatables.net/buttons/1.0.3/js/buttons.html5.min.js"></script>
    <script type="text/javascript" src="https://cdn.datatables.net/buttons/1.0.3/js/buttons.print.min.js"></script>
    <script type="text/javascript" src="https://cdn.datatables.net/buttons/1.0.3/js/buttons.colVis.min.js"></script>
    <script type="text/javascript" src="https://cdn.rawgit.com/bpampuch/pdfmake/0.1.18/build/pdfmake.min.js"></script>
    <script type="text/javascript" src="https://cdn.rawgit.com/bpampuch/pdfmake/0.1.18/build/vfs_fonts.js"></script>
    <script type="text/javascript" src="https://cdn.rawgit.com/bpampuch/pdfmake/0.1.18/build/vfs_fonts.js"></script>
    <script type="text/javascript" src="yadcf.js"></script>
    <script type="text/javascript" src="app.js"></script>
  </head>

  <body ng-controller="MainCtrl">
    <div style="width:600px; background-color:rgb(200,200,200); border:1px solid black; border-radius:5px;">
      <datatable-wrapper data='data' button-def='buttons'></datatable-wrapper>
    </div>
    </body>

</html>
/* Put your css in here */

tfoot {
    display: table-header-group !important;
}

.hide {
	display: none;
}

.inuse, .ui-slider-range .inuse, .yadcf-filter-range-number-slider .inuse {
	background: #8BBEF0;
}

.yadcf-filter-reset-button {
	display: inline-block;
}

.yadcf-filter-reset-button.range-number-slider-reset-button{
	position: relative;
	top: -6px;	
}

.yadcf-filter {
	padding-right: 4px;
	padding-left: 4px;
	padding-bottom: 3px;
	padding-top: 3px;
}

.yadcf-filter > option{
    background: white;
}

.ui-autocomplete .ui-menu-item { 
	font-size:13px;
}

#ui-datepicker-div { 
	font-size:13px;
}
.yadcf-filter-wrapper {
	display: inline-block;
	white-space: nowrap;
	margin-left: 2px;
}

.yadcf-filter-range-number {
	width: 40px;
}

.yadcf-filter-range-number-seperator {
	margin-left: 10px;
	margin-right: 10px;
}

.yadcf-filter-range-date {
	width: 80px;
}

.yadcf-filter-range-date-seperator {
	margin-left: 10px;
	margin-right: 10px;
}

.yadcf-filter-wrapper-inner {
	display: inline-block;
	border: 1px solid #ABADB3;
	padding-left: 2px;
	padding-right: 2px;
}

.yadcf-number-slider-filter-wrapper-inner {
	display: inline-block;
	width: 200px;
	margin-bottom: 7px;
}

.yadcf-filter-range-number-slider .ui-slider-handle {
	width: 10px;
	height: 10px;
	margin-top: 1px;
}

.yadcf-filter-range-number-slider .ui-slider-range {
	position: relative;
	height: 5px;
}

.yadcf-filter-range-number-slider {
	height: 5px;
	margin-left: 6px;
	margin-right: 6px;
}

.yadcf-filter-range-number-slider {
    overflow: visible;
}

.yadcf-number-slider-filter-wrapper-inner .yadcf-filter-range-number-slider-min-tip {
	font-size: 13px;
	font-weight: normal;
	position: absolute;
	outline-style: none;
}

.yadcf-number-slider-filter-wrapper-inner .yadcf-filter-range-number-slider-max-tip {
	font-size: 13px;
	font-weight: normal;
	position:absolute;
	outline-style: none;
}

.yadcf-number-slider-filter-wrapper-inner .yadcf-filter-range-number-slider-min-tip-inner {
	position:absolute;
	top: 11px;
}

.yadcf-number-slider-filter-wrapper-inner .yadcf-filter-range-number-slider-max-tip-inner {
	position:absolute;
	top: 11px;
}

.yadcf-exclude-wrapper {
	display: inline-block;
	vertical-align: middle;
	margin-right: 5px;
}
.yadcf-label.small {
	font-size: 10px;
}


/*----------------------------------------------------------------*/

/*! jQuery UI - v1.9.0 - 2012-10-05
* http://jqueryui.com
* Includes: jquery.ui.core.css, jquery.ui.accordion.css, jquery.ui.autocomplete.css, jquery.ui.button.css, jquery.ui.datepicker.css, jquery.ui.dialog.css, jquery.ui.menu.css, jquery.ui.progressbar.css, jquery.ui.resizable.css, jquery.ui.selectable.css, jquery.ui.slider.css, jquery.ui.spinner.css, jquery.ui.tabs.css, jquery.ui.tooltip.css, jquery.ui.theme.css
* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */

/* Layout helpers
----------------------------------*/
.ui-helper-hidden { display: none; }
.ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); }
.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; }
.ui-helper-clearfix:before, .ui-helper-clearfix:after { content: ""; display: table; }
.ui-helper-clearfix:after { clear: both; }
.ui-helper-clearfix { zoom: 1; }
.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); }


/* Interaction Cues
----------------------------------*/
.ui-state-disabled { cursor: default !important; }


/* Icons
----------------------------------*/

/* states and images */
.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; }


/* Misc visuals
----------------------------------*/

/* Overlays */
.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }

.ui-accordion .ui-accordion-header { display: block; cursor: pointer; position: relative; margin-top: 2px; padding: .5em .5em .5em .7em; zoom: 1; }
.ui-accordion .ui-accordion-icons { padding-left: 2.2em; }
.ui-accordion .ui-accordion-noicons { padding-left: .7em; }
.ui-accordion .ui-accordion-icons .ui-accordion-icons { padding-left: 2.2em; }
.ui-accordion .ui-accordion-header .ui-accordion-header-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; }
.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; overflow: auto; zoom: 1; }

.ui-autocomplete { position: absolute; cursor: default; }	

/* workarounds */
* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */

.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */
.ui-button, .ui-button:link, .ui-button:visited, .ui-button:hover, .ui-button:active { text-decoration: none; }
.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */
button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */
.ui-button-icons-only { width: 3.4em; } 
button.ui-button-icons-only { width: 3.7em; } 

/*button text element */
.ui-button .ui-button-text { display: block; line-height: 1.4;  }
.ui-button-text-only .ui-button-text { padding: .4em 1em; }
.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; }
.ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; }
.ui-button-text-icon-secondary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 2.1em .4em 1em; }
.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; }
/* no icon support for input elements, provide padding by default */
input.ui-button { padding: .4em 1em; }

/*button icon element(s) */
.ui-button-icon-only .ui-icon, .ui-button-text-icon-primary .ui-icon, .ui-button-text-icon-secondary .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; }
.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; }
.ui-button-text-icon-primary .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; }
.ui-button-text-icon-secondary .ui-button-icon-secondary, .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; }
.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; }

/*button sets*/
.ui-buttonset { margin-right: 7px; }
.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; }

/* workarounds */
button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */

.ui-datepicker { width: 17em; padding: .2em .2em 0; display: none; }
.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; }
.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; }
.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; }
.ui-datepicker .ui-datepicker-prev { left:2px; }
.ui-datepicker .ui-datepicker-next { right:2px; }
.ui-datepicker .ui-datepicker-prev-hover { left:1px; }
.ui-datepicker .ui-datepicker-next-hover { right:1px; }
.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px;  }
.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; }
.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; }
.ui-datepicker select.ui-datepicker-month-year {width: 100%;}
.ui-datepicker select.ui-datepicker-month, 
.ui-datepicker select.ui-datepicker-year { width: 49%;}
.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; }
.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0;  }
.ui-datepicker td { border: 0; padding: 1px; }
.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; }
.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; }
.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; }
.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; }

/* with multiple calendars */
.ui-datepicker.ui-datepicker-multi { width:auto; }
.ui-datepicker-multi .ui-datepicker-group { float:left; }
.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; }
.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; }
.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; }
.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; }
.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; }
.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; }
.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; }
.ui-datepicker-row-break { clear:both; width:100%; font-size:0em; }

/* RTL support */
.ui-datepicker-rtl { direction: rtl; }
.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; }
.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; }
.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; }
.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; }
.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; }
.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; }
.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; }
.ui-datepicker-rtl .ui-datepicker-group { float:right; }
.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; }

/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */
.ui-datepicker-cover {
    position: absolute; /*must have*/
    z-index: -1; /*must have*/
    filter: mask(); /*must have*/
    top: -4px; /*must have*/
    left: -4px; /*must have*/
    width: 200px; /*must have*/
    height: 200px; /*must have*/
}
.ui-dialog { position: absolute; padding: .2em; width: 300px; overflow: hidden; }
.ui-dialog .ui-dialog-titlebar { padding: .4em 1em; position: relative;  }
.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .1em 0; }
.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; }
.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; }
.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; }
.ui-dialog .ui-dialog-content { position: relative; border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; }
.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; }
.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { float: right; }
.ui-dialog .ui-dialog-buttonpane button { margin: .5em .4em .5em 0; cursor: pointer; }
.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; }
.ui-draggable .ui-dialog-titlebar { cursor: move; }

.ui-menu { list-style:none; padding: 2px; margin: 0; display:block; outline: none; }
.ui-menu .ui-menu { margin-top: -3px; position: absolute; }
.ui-menu .ui-menu-item { margin: 0; padding: 0; zoom: 1; width: 100%; }
.ui-menu .ui-menu-divider { margin: 5px -2px 5px -2px; height: 0; font-size: 0; line-height: 0; border-width: 1px 0 0 0; }
.ui-menu .ui-menu-item a { text-decoration: none; display: block; padding: 2px .4em; line-height: 1.5; zoom: 1; font-weight: normal; }
.ui-menu .ui-menu-item a.ui-state-focus,
.ui-menu .ui-menu-item a.ui-state-active { font-weight: normal; margin: -1px; }

.ui-menu .ui-state-disabled { font-weight: normal; margin: .4em 0 .2em; line-height: 1.5; }
.ui-menu .ui-state-disabled a { cursor: default; }

/* icon support */
.ui-menu-icons { position: relative; }
.ui-menu-icons .ui-menu-item a { position: relative; padding-left: 2em; }

/* left-aligned */
.ui-menu .ui-icon { position: absolute; top: .2em; left: .2em; }

/* right-aligned */
.ui-menu .ui-menu-icon { position: static; float: right; }

.ui-progressbar { height:2em; text-align: left; overflow: hidden; }
.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; }
.ui-resizable { position: relative;}
.ui-resizable-handle { position: absolute;font-size: 0.1px; display: block; }
.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; }
.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; }
.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; }
.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; }
.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; }
.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; }
.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; }
.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; }
.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}
.ui-selectable-helper { position: absolute; z-index: 100; border:1px dotted black; }

.ui-slider { position: relative; text-align: left; }
.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; }
.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; }

.ui-slider-horizontal { height: .8em; }
.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; }
.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; }
.ui-slider-horizontal .ui-slider-range-min { left: 0; }
.ui-slider-horizontal .ui-slider-range-max { right: 0; }

.ui-slider-vertical { width: .8em; height: 100px; }
.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; }
.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; }
.ui-slider-vertical .ui-slider-range-min { bottom: 0; }
.ui-slider-vertical .ui-slider-range-max { top: 0; }
.ui-spinner { position:relative; display: inline-block; overflow: hidden; padding: 0; vertical-align: middle; }
.ui-spinner-input { border: none; background: none; padding: 0; margin: .2em 0; vertical-align: middle; margin-left: .4em; margin-right: 22px; }
.ui-spinner-button { width: 16px; height: 50%; font-size: .5em; padding: 0; margin: 0; z-index: 100; text-align: center; position: absolute; cursor: default; display: block; overflow: hidden; right: 0; }
.ui-spinner a.ui-spinner-button { border-top: none; border-bottom: none; border-right: none; } /* more specificity required here to overide default borders */
.ui-spinner .ui-icon { position: absolute; margin-top: -8px; top: 50%; left: 0; } /* vertical centre icon */
.ui-spinner-up { top: 0; }
.ui-spinner-down { bottom: 0; }

/* TR overrides */
span.ui-spinner { background: none; }
.ui-spinner .ui-icon-triangle-1-s {
	/* need to fix icons sprite */
	background-position:-65px -16px;
}

.ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
.ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; }
.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 0; margin: 1px .2em 0 0; border-bottom: 0; padding: 0; white-space: nowrap; }
.ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; }
.ui-tabs .ui-tabs-nav li.ui-tabs-active { margin-bottom: -1px; padding-bottom: 1px; }
.ui-tabs .ui-tabs-nav li.ui-tabs-active a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-tabs-loading a { cursor: text; }
.ui-tabs .ui-tabs-nav li a, .ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
.ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; }

.ui-tooltip {
	padding:8px;
	position:absolute;
	z-index:9999;
	-o-box-shadow: 0 0 5px #aaa;
	-moz-box-shadow: 0 0 5px #aaa;
	-webkit-box-shadow: 0 0 5px #aaa;
	box-shadow: 0 0 5px #aaa;
}
/* Fades and background-images don't work well together in IE6, drop the image */
* html .ui-tooltip {
	background-image: none;
}
body .ui-tooltip { border-width:2px; }

/* Component containers
----------------------------------*/
.ui-widget { font-family: Verdana,Arial,sans-serif/*{ffDefault}*/; font-size: 1.1em/*{fsDefault}*/; }
.ui-widget .ui-widget { font-size: 1em; }
.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Verdana,Arial,sans-serif/*{ffDefault}*/; font-size: 1em; }
.ui-widget-content { border: 1px solid #aaaaaa/*{borderColorContent}*/; background: #ffffff/*{bgColorContent}*/ url(images/ui-bg_flat_75_ffffff_40x100.png)/*{bgImgUrlContent}*/ 50%/*{bgContentXPos}*/ 50%/*{bgContentYPos}*/ repeat-x/*{bgContentRepeat}*/; color: #222222/*{fcContent}*/; }
.ui-widget-content a { color: #222222/*{fcContent}*/; }
.ui-widget-header { border: 1px solid #aaaaaa/*{borderColorHeader}*/; background: #cccccc/*{bgColorHeader}*/ url(images/ui-bg_highlight-soft_75_cccccc_1x100.png)/*{bgImgUrlHeader}*/ 50%/*{bgHeaderXPos}*/ 50%/*{bgHeaderYPos}*/ repeat-x/*{bgHeaderRepeat}*/; color: #222222/*{fcHeader}*/; font-weight: bold; }
.ui-widget-header a { color: #222222/*{fcHeader}*/; }

/* Interaction states
----------------------------------*/
.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #d3d3d3/*{borderColorDefault}*/; background: #e6e6e6/*{bgColorDefault}*/ url(images/ui-bg_glass_75_e6e6e6_1x400.png)/*{bgImgUrlDefault}*/ 50%/*{bgDefaultXPos}*/ 50%/*{bgDefaultYPos}*/ repeat-x/*{bgDefaultRepeat}*/; font-weight: normal/*{fwDefault}*/; color: #555555/*{fcDefault}*/; }
.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #555555/*{fcDefault}*/; text-decoration: none; }
.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #999999/*{borderColorHover}*/; background: #dadada/*{bgColorHover}*/ url(images/ui-bg_glass_75_dadada_1x400.png)/*{bgImgUrlHover}*/ 50%/*{bgHoverXPos}*/ 50%/*{bgHoverYPos}*/ repeat-x/*{bgHoverRepeat}*/; font-weight: normal/*{fwDefault}*/; color: #212121/*{fcHover}*/; }
.ui-state-hover a, .ui-state-hover a:hover { color: #212121/*{fcHover}*/; text-decoration: none; }
.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #aaaaaa/*{borderColorActive}*/; background: #ffffff/*{bgColorActive}*/ url(images/ui-bg_glass_65_ffffff_1x400.png)/*{bgImgUrlActive}*/ 50%/*{bgActiveXPos}*/ 50%/*{bgActiveYPos}*/ repeat-x/*{bgActiveRepeat}*/; font-weight: normal/*{fwDefault}*/; color: #212121/*{fcActive}*/; }
.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #212121/*{fcActive}*/; text-decoration: none; }

/* Interaction Cues
----------------------------------*/
.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight  {border: 1px solid #fcefa1/*{borderColorHighlight}*/; background: #fbf9ee/*{bgColorHighlight}*/ url(images/ui-bg_glass_55_fbf9ee_1x400.png)/*{bgImgUrlHighlight}*/ 50%/*{bgHighlightXPos}*/ 50%/*{bgHighlightYPos}*/ repeat-x/*{bgHighlightRepeat}*/; color: #363636/*{fcHighlight}*/; }
.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636/*{fcHighlight}*/; }
.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a/*{borderColorError}*/; background: #fef1ec/*{bgColorError}*/ url(images/ui-bg_glass_95_fef1ec_1x400.png)/*{bgImgUrlError}*/ 50%/*{bgErrorXPos}*/ 50%/*{bgErrorYPos}*/ repeat-x/*{bgErrorRepeat}*/; color: #cd0a0a/*{fcError}*/; }
.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #cd0a0a/*{fcError}*/; }
.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #cd0a0a/*{fcError}*/; }
.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; }
.ui-priority-secondary, .ui-widget-content .ui-priority-secondary,  .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; }
.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; }

/* Icons
----------------------------------*/

/* states and images */
.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png)/*{iconsContent}*/; }
.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png)/*{iconsContent}*/; }
.ui-widget-header .ui-icon {background-image: url(images/ui-icons_222222_256x240.png)/*{iconsHeader}*/; }
.ui-state-default .ui-icon { background-image: url(images/ui-icons_888888_256x240.png)/*{iconsDefault}*/; }
.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_454545_256x240.png)/*{iconsHover}*/; }
.ui-state-active .ui-icon {background-image: url(images/ui-icons_454545_256x240.png)/*{iconsActive}*/; }
.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_2e83ff_256x240.png)/*{iconsHighlight}*/; }
.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_cd0a0a_256x240.png)/*{iconsError}*/; }

/* positioning */
.ui-icon-carat-1-n { background-position: 0 0; }
.ui-icon-carat-1-ne { background-position: -16px 0; }
.ui-icon-carat-1-e { background-position: -32px 0; }
.ui-icon-carat-1-se { background-position: -48px 0; }
.ui-icon-carat-1-s { background-position: -64px 0; }
.ui-icon-carat-1-sw { background-position: -80px 0; }
.ui-icon-carat-1-w { background-position: -96px 0; }
.ui-icon-carat-1-nw { background-position: -112px 0; }
.ui-icon-carat-2-n-s { background-position: -128px 0; }
.ui-icon-carat-2-e-w { background-position: -144px 0; }
.ui-icon-triangle-1-n { background-position: 0 -16px; }
.ui-icon-triangle-1-ne { background-position: -16px -16px; }
.ui-icon-triangle-1-e { background-position: -32px -16px; }
.ui-icon-triangle-1-se { background-position: -48px -16px; }
.ui-icon-triangle-1-s { background-position: -64px -16px; }
.ui-icon-triangle-1-sw { background-position: -80px -16px; }
.ui-icon-triangle-1-w { background-position: -96px -16px; }
.ui-icon-triangle-1-nw { background-position: -112px -16px; }
.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
.ui-icon-arrow-1-n { background-position: 0 -32px; }
.ui-icon-arrow-1-ne { background-position: -16px -32px; }
.ui-icon-arrow-1-e { background-position: -32px -32px; }
.ui-icon-arrow-1-se { background-position: -48px -32px; }
.ui-icon-arrow-1-s { background-position: -64px -32px; }
.ui-icon-arrow-1-sw { background-position: -80px -32px; }
.ui-icon-arrow-1-w { background-position: -96px -32px; }
.ui-icon-arrow-1-nw { background-position: -112px -32px; }
.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
.ui-icon-arrow-4 { background-position: 0 -80px; }
.ui-icon-arrow-4-diag { background-position: -16px -80px; }
.ui-icon-extlink { background-position: -32px -80px; }
.ui-icon-newwin { background-position: -48px -80px; }
.ui-icon-refresh { background-position: -64px -80px; }
.ui-icon-shuffle { background-position: -80px -80px; }
.ui-icon-transfer-e-w { background-position: -96px -80px; }
.ui-icon-transferthick-e-w { background-position: -112px -80px; }
.ui-icon-folder-collapsed { background-position: 0 -96px; }
.ui-icon-folder-open { background-position: -16px -96px; }
.ui-icon-document { background-position: -32px -96px; }
.ui-icon-document-b { background-position: -48px -96px; }
.ui-icon-note { background-position: -64px -96px; }
.ui-icon-mail-closed { background-position: -80px -96px; }
.ui-icon-mail-open { background-position: -96px -96px; }
.ui-icon-suitcase { background-position: -112px -96px; }
.ui-icon-comment { background-position: -128px -96px; }
.ui-icon-person { background-position: -144px -96px; }
.ui-icon-print { background-position: -160px -96px; }
.ui-icon-trash { background-position: -176px -96px; }
.ui-icon-locked { background-position: -192px -96px; }
.ui-icon-unlocked { background-position: -208px -96px; }
.ui-icon-bookmark { background-position: -224px -96px; }
.ui-icon-tag { background-position: -240px -96px; }
.ui-icon-home { background-position: 0 -112px; }
.ui-icon-flag { background-position: -16px -112px; }
.ui-icon-calendar { background-position: -32px -112px; }
.ui-icon-cart { background-position: -48px -112px; }
.ui-icon-pencil { background-position: -64px -112px; }
.ui-icon-clock { background-position: -80px -112px; }
.ui-icon-disk { background-position: -96px -112px; }
.ui-icon-calculator { background-position: -112px -112px; }
.ui-icon-zoomin { background-position: -128px -112px; }
.ui-icon-zoomout { background-position: -144px -112px; }
.ui-icon-search { background-position: -160px -112px; }
.ui-icon-wrench { background-position: -176px -112px; }
.ui-icon-gear { background-position: -192px -112px; }
.ui-icon-heart { background-position: -208px -112px; }
.ui-icon-star { background-position: -224px -112px; }
.ui-icon-link { background-position: -240px -112px; }
.ui-icon-cancel { background-position: 0 -128px; }
.ui-icon-plus { background-position: -16px -128px; }
.ui-icon-plusthick { background-position: -32px -128px; }
.ui-icon-minus { background-position: -48px -128px; }
.ui-icon-minusthick { background-position: -64px -128px; }
.ui-icon-close { background-position: -80px -128px; }
.ui-icon-closethick { background-position: -96px -128px; }
.ui-icon-key { background-position: -112px -128px; }
.ui-icon-lightbulb { background-position: -128px -128px; }
.ui-icon-scissors { background-position: -144px -128px; }
.ui-icon-clipboard { background-position: -160px -128px; }
.ui-icon-copy { background-position: -176px -128px; }
.ui-icon-contact { background-position: -192px -128px; }
.ui-icon-image { background-position: -208px -128px; }
.ui-icon-video { background-position: -224px -128px; }
.ui-icon-script { background-position: -240px -128px; }
.ui-icon-alert { background-position: 0 -144px; }
.ui-icon-info { background-position: -16px -144px; }
.ui-icon-notice { background-position: -32px -144px; }
.ui-icon-help { background-position: -48px -144px; }
.ui-icon-check { background-position: -64px -144px; }
.ui-icon-bullet { background-position: -80px -144px; }
.ui-icon-radio-on { background-position: -96px -144px; }
.ui-icon-radio-off { background-position: -112px -144px; }
.ui-icon-pin-w { background-position: -128px -144px; }
.ui-icon-pin-s { background-position: -144px -144px; }
.ui-icon-play { background-position: 0 -160px; }
.ui-icon-pause { background-position: -16px -160px; }
.ui-icon-seek-next { background-position: -32px -160px; }
.ui-icon-seek-prev { background-position: -48px -160px; }
.ui-icon-seek-end { background-position: -64px -160px; }
.ui-icon-seek-start { background-position: -80px -160px; }
/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
.ui-icon-seek-first { background-position: -80px -160px; }
.ui-icon-stop { background-position: -96px -160px; }
.ui-icon-eject { background-position: -112px -160px; }
.ui-icon-volume-off { background-position: -128px -160px; }
.ui-icon-volume-on { background-position: -144px -160px; }
.ui-icon-power { background-position: 0 -176px; }
.ui-icon-signal-diag { background-position: -16px -176px; }
.ui-icon-signal { background-position: -32px -176px; }
.ui-icon-battery-0 { background-position: -48px -176px; }
.ui-icon-battery-1 { background-position: -64px -176px; }
.ui-icon-battery-2 { background-position: -80px -176px; }
.ui-icon-battery-3 { background-position: -96px -176px; }
.ui-icon-circle-plus { background-position: 0 -192px; }
.ui-icon-circle-minus { background-position: -16px -192px; }
.ui-icon-circle-close { background-position: -32px -192px; }
.ui-icon-circle-triangle-e { background-position: -48px -192px; }
.ui-icon-circle-triangle-s { background-position: -64px -192px; }
.ui-icon-circle-triangle-w { background-position: -80px -192px; }
.ui-icon-circle-triangle-n { background-position: -96px -192px; }
.ui-icon-circle-arrow-e { background-position: -112px -192px; }
.ui-icon-circle-arrow-s { background-position: -128px -192px; }
.ui-icon-circle-arrow-w { background-position: -144px -192px; }
.ui-icon-circle-arrow-n { background-position: -160px -192px; }
.ui-icon-circle-zoomin { background-position: -176px -192px; }
.ui-icon-circle-zoomout { background-position: -192px -192px; }
.ui-icon-circle-check { background-position: -208px -192px; }
.ui-icon-circlesmall-plus { background-position: 0 -208px; }
.ui-icon-circlesmall-minus { background-position: -16px -208px; }
.ui-icon-circlesmall-close { background-position: -32px -208px; }
.ui-icon-squaresmall-plus { background-position: -48px -208px; }
.ui-icon-squaresmall-minus { background-position: -64px -208px; }
.ui-icon-squaresmall-close { background-position: -80px -208px; }
.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
.ui-icon-grip-diagonal-se { background-position: -80px -224px; }


/* Misc visuals
----------------------------------*/

/* Corner radius */
.ui-corner-all, .ui-corner-top, .ui-corner-left, .ui-corner-tl { -moz-border-radius-topleft: 4px/*{cornerRadius}*/; -webkit-border-top-left-radius: 4px/*{cornerRadius}*/; -khtml-border-top-left-radius: 4px/*{cornerRadius}*/; border-top-left-radius: 4px/*{cornerRadius}*/; }
.ui-corner-all, .ui-corner-top, .ui-corner-right, .ui-corner-tr { -moz-border-radius-topright: 4px/*{cornerRadius}*/; -webkit-border-top-right-radius: 4px/*{cornerRadius}*/; -khtml-border-top-right-radius: 4px/*{cornerRadius}*/; border-top-right-radius: 4px/*{cornerRadius}*/; }
.ui-corner-all, .ui-corner-bottom, .ui-corner-left, .ui-corner-bl { -moz-border-radius-bottomleft: 4px/*{cornerRadius}*/; -webkit-border-bottom-left-radius: 4px/*{cornerRadius}*/; -khtml-border-bottom-left-radius: 4px/*{cornerRadius}*/; border-bottom-left-radius: 4px/*{cornerRadius}*/; }
.ui-corner-all, .ui-corner-bottom, .ui-corner-right, .ui-corner-br { -moz-border-radius-bottomright: 4px/*{cornerRadius}*/; -webkit-border-bottom-right-radius: 4px/*{cornerRadius}*/; -khtml-border-bottom-right-radius: 4px/*{cornerRadius}*/; border-bottom-right-radius: 4px/*{cornerRadius}*/; }

/* Overlays */
.ui-widget-overlay { background: #aaaaaa/*{bgColorOverlay}*/ url(images/ui-bg_flat_0_aaaaaa_40x100.png)/*{bgImgUrlOverlay}*/ 50%/*{bgOverlayXPos}*/ 50%/*{bgOverlayYPos}*/ repeat-x/*{bgOverlayRepeat}*/; opacity: .3;filter:Alpha(Opacity=30)/*{opacityOverlay}*/; }
.ui-widget-shadow { margin: -8px/*{offsetTopShadow}*/ 0 0 -8px/*{offsetLeftShadow}*/; padding: 8px/*{thicknessShadow}*/; background: #aaaaaa/*{bgColorShadow}*/ url(images/ui-bg_flat_0_aaaaaa_40x100.png)/*{bgImgUrlShadow}*/ 50%/*{bgShadowXPos}*/ 50%/*{bgShadowYPos}*/ repeat-x/*{bgShadowRepeat}*/; opacity: .3;filter:Alpha(Opacity=30)/*{opacityShadow}*/; -moz-border-radius: 8px/*{cornerRadiusShadow}*/; -khtml-border-radius: 8px/*{cornerRadiusShadow}*/; -webkit-border-radius: 8px/*{cornerRadiusShadow}*/; border-radius: 8px/*{cornerRadiusShadow}*/; }
    <div id="external_filter_container"></div>
    <table datatable="" dt-options="dt.options" dt-columns="dt.columns" class="row-border hover" dt-instance="dt.instance">
        
    </table>
    <button ng-click="alertFunc()">rerender</button>

/*!
 * angular-datatables - v0.5.0
 * https://github.com/l-lin/angular-datatables
 * License: MIT
 */
(function (window, document, $, angular) {

'use strict';

angular.module('datatables.directive', ['datatables.instances', 'datatables.renderer', 'datatables.options', 'datatables.util'])
    .directive('datatable', dataTable);

/* @ngInject */
function dataTable($q, $http, DTRendererFactory, DTRendererService, DTPropertyUtil) {
    compileDirective.$inject = ['tElm'];
    ControllerDirective.$inject = ['$scope'];
    return {
        restrict: 'A',
        scope: {
            dtOptions: '=',
            dtColumns: '=',
            dtColumnDefs: '=',
            datatable: '@',
            dtInstance: '='
        },
        compile: compileDirective,
        controller: ControllerDirective
    };

    /* @ngInject */
    function compileDirective(tElm) {
        var _staticHTML = tElm[0].innerHTML;

        return function postLink($scope, $elem, iAttrs, ctrl) {
            function handleChanges(newVal, oldVal) {
                if (newVal !== oldVal) {
                    ctrl.render($elem, ctrl.buildOptionsPromise(), _staticHTML);
                }
            }

            // Options can hold heavy data, and other deep/large objects.
            // watchcollection can improve this by only watching shallowly
            var watchFunction = iAttrs.dtDisableDeepWatchers ? '$watchCollection' : '$watch';
            angular.forEach(['dtColumns', 'dtColumnDefs', 'dtOptions'], function(tableDefField) {
                $scope[watchFunction].call($scope, tableDefField, handleChanges, true);
            });
            DTRendererService.showLoading($elem);
            ctrl.render($elem, ctrl.buildOptionsPromise(), _staticHTML);
        };
    }

    /* @ngInject */
    function ControllerDirective($scope) {
        var _dtInstance;
        var vm = this;
        
        
        $scope.$watch('dtOptions', function(){
          //alert(JSON.stringify($scope.dtOptions));
        });
        
        vm.buildOptionsPromise = buildOptionsPromise;
        vm.render = render;
        function buildOptionsPromise() {
            var defer = $q.defer();
            // Build options
            $q.all([
                $q.when($scope.dtOptions),
                $q.when($scope.dtColumns),
                $q.when($scope.dtColumnDefs)
            ]).then(function(results) {
                var dtOptions = results[0],
                    dtColumns = results[1],
                    dtColumnDefs = results[2];
                // Since Angular 1.3, the promise throws a "Maximum call stack size exceeded" when cloning
                // See https://github.com/l-lin/angular-datatables/issues/110
                DTPropertyUtil.deleteProperty(dtOptions, '$promise');
                DTPropertyUtil.deleteProperty(dtColumns, '$promise');
                DTPropertyUtil.deleteProperty(dtColumnDefs, '$promise');
                var options;
                if (angular.isDefined(dtOptions)) {
                    options = {};
                    angular.extend(options, dtOptions);
                    // Set the columns
                    if (angular.isArray(dtColumns)) {
                        options.aoColumns = dtColumns;
                    }

                    // Set the column defs
                    if (angular.isArray(dtColumnDefs)) {
                        options.aoColumnDefs = dtColumnDefs;
                    }

                    // HACK to resolve the language source manually instead of DT
                    // See https://github.com/l-lin/angular-datatables/issues/181
                    if (options.language && options.language.url) {
                        var languageDefer = $q.defer();
                        $http.get(options.language.url).success(function(language) {
                            languageDefer.resolve(language);
                        });
                        options.language = languageDefer.promise;
                    }

                }
                return DTPropertyUtil.resolveObjectPromises(options, ['data', 'aaData', 'fnPromise']);
            }).then(function(options) {
                defer.resolve(options);
            });
            return defer.promise;
        }

        function render($elem, optionsPromise, staticHTML) {
            optionsPromise.then(function(options) {
                DTRendererService.preRender(options);

                var isNgDisplay = $scope.datatable && $scope.datatable === 'ng';
                // Render dataTable
                if (_dtInstance && _dtInstance._renderer) {
                    _dtInstance._renderer.withOptions(options)
                        .render($elem, $scope, staticHTML).then(function(dtInstance) {
                            _dtInstance = dtInstance;
                            _setDTInstance(dtInstance);
                        });
                } else {
                    DTRendererFactory.fromOptions(options, isNgDisplay)
                        .render($elem, $scope, staticHTML).then(function(dtInstance) {
                            _dtInstance = dtInstance;
                            _setDTInstance(dtInstance);
                        });
                }
            });
        }

        function _setDTInstance(dtInstance) {
            if (angular.isFunction($scope.dtInstance)) {
                $scope.dtInstance(dtInstance);
            } else if (angular.isDefined($scope.dtInstance)) {
                $scope.dtInstance = dtInstance;
            }
        }
    }
}
dataTable.$inject = ['$q', '$http', 'DTRendererFactory', 'DTRendererService', 'DTPropertyUtil'];

'use strict';
angular.module('datatables.factory', [])
    .factory('DTOptionsBuilder', dtOptionsBuilder)
    .factory('DTColumnBuilder', dtColumnBuilder)
    .factory('DTColumnDefBuilder', dtColumnDefBuilder)
    .factory('DTLoadingTemplate', dtLoadingTemplate);

/* @ngInject */
function dtOptionsBuilder() {
    /**
     * The wrapped datatables options class
     * @param sAjaxSource the ajax source to fetch the data
     * @param fnPromise the function that returns a promise to fetch the data
     */
    var DTOptions = {
        hasOverrideDom: false,

        /**
         * Add the option to the datatables optoins
         * @param key the key of the option
         * @param value an object or a function of the option
         * @returns {DTOptions} the options
         */
        withOption: function(key, value) {
            if (angular.isString(key)) {
                this[key] = value;
            }
            return this;
        },

        /**
         * Add the Ajax source to the options.
         * This corresponds to the "ajax" option
         * @param ajax the ajax source
         * @returns {DTOptions} the options
         */
        withSource: function(ajax) {
            this.ajax = ajax;
            return this;
        },

        /**
         * Add the ajax data properties.
         * @param sAjaxDataProp the ajax data property
         * @returns {DTOptions} the options
         */
        withDataProp: function(sAjaxDataProp) {
            this.sAjaxDataProp = sAjaxDataProp;
            return this;
        },

        /**
         * Set the server data function.
         * @param fn the function of the server retrieval
         * @returns {DTOptions} the options
         */
        withFnServerData: function(fn) {
            if (!angular.isFunction(fn)) {
                throw new Error('The parameter must be a function');
            }
            this.fnServerData = fn;
            return this;
        },

        /**
         * Set the pagination type.
         * @param sPaginationType the pagination type
         * @returns {DTOptions} the options
         */
        withPaginationType: function(sPaginationType) {
            if (angular.isString(sPaginationType)) {
                this.sPaginationType = sPaginationType;
            } else {
                throw new Error('The pagination type must be provided');
            }
            return this;
        },

        /**
         * Set the language of the datatables
         * @param language the language
         * @returns {DTOptions} the options
         */
        withLanguage: function(language) {
            this.language = language;
            return this;
        },

        /**
         * Set the language source
         * @param languageSource the language source
         * @returns {DTOptions} the options
         */
        withLanguageSource: function(languageSource) {
            return this.withLanguage({
                url: languageSource
            });
        },

        /**
         * Set default number of items per page to display
         * @param iDisplayLength the number of items per page
         * @returns {DTOptions} the options
         */
        withDisplayLength: function(iDisplayLength) {
            this.iDisplayLength = iDisplayLength;
            return this;
        },

        /**
         * Set the promise to fetch the data
         * @param fnPromise the function that returns a promise
         * @returns {DTOptions} the options
         */
        withFnPromise: function(fnPromise) {
            this.fnPromise = fnPromise;
            return this;
        },

        /**
         * Set the Dom of the DataTables.
         * @param dom the dom
         * @returns {DTOptions} the options
         */
        withDOM: function(dom) {
            this.dom = dom;
            return this;
        }
    };

    return {
        /**
         * Create a wrapped datatables options
         * @returns {DTOptions} a wrapped datatables option
         */
        newOptions: function() {
            return Object.create(DTOptions);
        },
        /**
         * Create a wrapped datatables options with the ajax source setted
         * @param ajax the ajax source
         * @returns {DTOptions} a wrapped datatables option
         */
        fromSource: function(ajax) {
            var options = Object.create(DTOptions);
            options.ajax = ajax;
            return options;
        },
        /**
         * Create a wrapped datatables options with the data promise.
         * @param fnPromise the function that returns a promise to fetch the data
         * @returns {DTOptions} a wrapped datatables option
         */
        fromFnPromise: function(fnPromise) {
            var options = Object.create(DTOptions);
            options.fnPromise = fnPromise;
            return options;
        }
    };
}

function dtColumnBuilder() {
    /**
     * The wrapped datatables column
     * @param mData the data to display of the column
     * @param sTitle the sTitle of the column title to display in the DOM
     */
    var DTColumn = {
        /**
         * Add the option of the column
         * @param key the key of the option
         * @param value an object or a function of the option
         * @returns {DTColumn} the wrapped datatables column
         */
        withOption: function(key, value) {
            if (angular.isString(key)) {
                this[key] = value;
            }
            return this;
        },

        /**
         * Set the title of the colum
         * @param sTitle the sTitle of the column
         * @returns {DTColumn} the wrapped datatables column
         */
        withTitle: function(sTitle) {
            this.sTitle = sTitle;
            return this;
        },

        /**
         * Set the CSS class of the column
         * @param sClass the CSS class
         * @returns {DTColumn} the wrapped datatables column
         */
        withClass: function(sClass) {
            this.sClass = sClass;
            return this;
        },

        /**
         * Hide the column
         * @returns {DTColumn} the wrapped datatables column
         */
        notVisible: function() {
            this.bVisible = false;
            return this;
        },

        /**
         * Set the column as not sortable
         * @returns {DTColumn} the wrapped datatables column
         */
        notSortable: function() {
            this.bSortable = false;
            return this;
        },

        /**
         * Render each cell with the given parameter
         * @mRender mRender the function/string to render the data
         * @returns {DTColumn} the wrapped datatables column
         */
        renderWith: function(mRender) {
            this.mRender = mRender;
            return this;
        }
    };

    return {
        /**
         * Create a new wrapped datatables column
         * @param mData the data of the column to display
         * @param sTitle the sTitle of the column title to display in the DOM
         * @returns {DTColumn} the wrapped datatables column
         */
        newColumn: function(mData, sTitle) {
            if (angular.isUndefined(mData)) {
                throw new Error('The parameter "mData" is not defined!');
            }
            var column = Object.create(DTColumn);
            column.mData = mData;
            if (angular.isString(sTitle)) {
                column.sTitle = sTitle;
            }
            return column;
        },
        DTColumn: DTColumn
    };
}

/* @ngInject */
function dtColumnDefBuilder(DTColumnBuilder) {
    return {
        newColumnDef: function(targets) {
            if (angular.isUndefined(targets)) {
                throw new Error('The parameter "targets" must be defined! See https://datatables.net/reference/option/columnDefs.targets');
            }
            var column = Object.create(DTColumnBuilder.DTColumn);
            if (angular.isArray(targets)) {
                column.aTargets = targets;
            } else {
                column.aTargets = [targets];
            }
            return column;
        }
    };
}
dtColumnDefBuilder.$inject = ['DTColumnBuilder'];

function dtLoadingTemplate() {
    return {
        html: '<h3 class="dt-loading">Loading...</h3>'
    };
}

'use strict';

angular.module('datatables.instances', ['datatables.util'])
    .factory('DTInstanceFactory', dtInstanceFactory);

function dtInstanceFactory() {
    var DTInstance = {
        reloadData: reloadData,
        changeData: changeData,
        rerender: rerender
    };
    return {
        newDTInstance: newDTInstance,
        copyDTProperties: copyDTProperties
    };

    function newDTInstance(renderer) {
        var dtInstance = Object.create(DTInstance);
        dtInstance._renderer = renderer;
        return dtInstance;
    }

    function copyDTProperties(result, dtInstance) {
        dtInstance.id = result.id;
        dtInstance.DataTable = result.DataTable;
        dtInstance.dataTable = result.dataTable;
    }

    function reloadData(callback, resetPaging) {
        /*jshint validthis:true */
        this._renderer.reloadData(callback, resetPaging);
    }

    function changeData(data) {
        /*jshint validthis:true */
        this._renderer.changeData(data);
    }

    function rerender() {
        /*jshint validthis:true */
        this._renderer.rerender();
    }
}

'use strict';

angular.module('datatables', ['datatables.directive', 'datatables.factory'])
    .run(initAngularDataTables);

/* @ngInject */
function initAngularDataTables() {
    if ($.fn.DataTable.Api) {
        /**
         * Register an API to destroy a DataTable without detaching the tbody so that we can add new data
         * when rendering with the "Angular way".
         */
        $.fn.DataTable.Api.register('ngDestroy()', function(remove) {
            remove = remove || false;

            return this.iterator('table', function(settings) {
                var orig = settings.nTableWrapper.parentNode;
                var classes = settings.oClasses;
                var table = settings.nTable;
                var tbody = settings.nTBody;
                var thead = settings.nTHead;
                var tfoot = settings.nTFoot;
                var jqTable = $(table);
                var jqTbody = $(tbody);
                var jqWrapper = $(settings.nTableWrapper);
                var rows = $.map(settings.aoData, function(r) {
                    return r.nTr;
                });
                var ien;

                // Flag to note that the table is currently being destroyed - no action
                // should be taken
                settings.bDestroying = true;

                // Fire off the destroy callbacks for plug-ins etc
                $.fn.DataTable.ext.internal._fnCallbackFire(settings, 'aoDestroyCallback', 'destroy', [settings]);

                // If not being removed from the document, make all columns visible
                if (!remove) {
                    new $.fn.DataTable.Api(settings).columns().visible(true);
                }

                // Blitz all `DT` namespaced events (these are internal events, the
                // lowercase, `dt` events are user subscribed and they are responsible
                // for removing them
                jqWrapper.unbind('.DT').find(':not(tbody *)').unbind('.DT');
                $(window).unbind('.DT-' + settings.sInstance);

                // When scrolling we had to break the table up - restore it
                if (table !== thead.parentNode) {
                    jqTable.children('thead').detach();
                    jqTable.append(thead);
                }

                if (tfoot && table !== tfoot.parentNode) {
                    jqTable.children('tfoot').detach();
                    jqTable.append(tfoot);
                }

                // Remove the DataTables generated nodes, events and classes
                jqTable.detach();
                jqWrapper.detach();

                settings.aaSorting = [];
                settings.aaSortingFixed = [];
                $.fn.DataTable.ext.internal._fnSortingClasses(settings);

                $(rows).removeClass(settings.asStripeClasses.join(' '));

                $('th, td', thead).removeClass(classes.sSortable + ' ' +
                    classes.sSortableAsc + ' ' + classes.sSortableDesc + ' ' + classes.sSortableNone
                );

                if (settings.bJUI) {
                    $('th span.' + classes.sSortIcon + ', td span.' + classes.sSortIcon, thead).detach();
                    $('th, td', thead).each(function() {
                        var wrapper = $('div.' + classes.sSortJUIWrapper, this);
                        $(this).append(wrapper.contents());
                        wrapper.detach();
                    });
                }

                // -------------------------------------------------------------------------
                // This is the only change with the "destroy()" API (with DT v1.10.1)
                // -------------------------------------------------------------------------
                if (!remove && orig) {
                    // insertBefore acts like appendChild if !arg[1]
                    if (orig.contains(settings.nTableReinsertBefore)) {
                        orig.insertBefore(table, settings.nTableReinsertBefore);
                    } else {
                        orig.appendChild(table);
                    }
                }
                // Add the TR elements back into the table in their original order
                // jqTbody.children().detach();
                // jqTbody.append( rows );
                // -------------------------------------------------------------------------

                // Restore the width of the original table - was read from the style property,
                // so we can restore directly to that
                jqTable
                    .css('width', settings.sDestroyWidth)
                    .removeClass(classes.sTable);

                // If the were originally stripe classes - then we add them back here.
                // Note this is not fool proof (for example if not all rows had stripe
                // classes - but it's a good effort without getting carried away
                ien = settings.asDestroyStripes.length;

                if (ien) {
                    jqTbody.children().each(function(i) {
                        $(this).addClass(settings.asDestroyStripes[i % ien]);
                    });
                }

                /* Remove the settings object from the settings array */
                var idx = $.inArray(settings, $.fn.DataTable.settings);
                if (idx !== -1) {
                    $.fn.DataTable.settings.splice(idx, 1);
                }
            });
        });
    }
}

'use strict';
angular.module('datatables.options', [])
    .constant('DT_DEFAULT_OPTIONS', {
        // Default dom
        dom: 'lfrtip',
        // Default ajax properties. See http://legacy.datatables.net/usage/options#sAjaxDataProp
        sAjaxDataProp: '',
        // Set default columns (used when none are provided)
        aoColumns: []
    })
    .service('DTDefaultOptions', dtDefaultOptions);

function dtDefaultOptions() {
    var options = {
        bootstrapOptions: {},
        setLanguageSource: setLanguageSource,
        setLanguage: setLanguage,
        setDisplayLength: setDisplayLength,
        setBootstrapOptions: setBootstrapOptions
    };

    return options;

    /**
     * Set the default language source for all datatables
     * @param sLanguageSource the language source
     * @returns {DTDefaultOptions} the default option config
     */
    function setLanguageSource(sLanguageSource) {
        $.extend($.fn.dataTable.defaults, {
            oLanguage: {
                sUrl: sLanguageSource
            }
        });
        return options;
    }

    /**
     * Set the language for all datatables
     * @param oLanguage the language
     * @returns {DTDefaultOptions} the default option config
     */
    function setLanguage(oLanguage) {
        $.extend(true, $.fn.dataTable.defaults, {
            oLanguage: oLanguage
        });
        return options;
    }

    /**
     * Set the default number of items to display for all datatables
     * @param iDisplayLength the number of items to display
     * @returns {DTDefaultOptions} the default option config
     */
    function setDisplayLength(iDisplayLength) {
        $.extend($.fn.dataTable.defaults, {
            iDisplayLength: iDisplayLength
        });
        return options;
    }

    /**
     * Set the default options to be use for Bootstrap integration.
     * See https://github.com/l-lin/angular-datatables/blob/dev/src/angular-datatables.bootstrap.options.js to check
     * what default options Angular DataTables is using.
     * @param oBootstrapOptions an object containing the default options for Bootstreap integration
     * @returns {DTDefaultOptions} the default option config
     */
    function setBootstrapOptions(oBootstrapOptions) {
        options.bootstrapOptions = oBootstrapOptions;
        return options;
    }
}

'use strict';
angular.module('datatables.renderer', ['datatables.instances', 'datatables.factory', 'datatables.options', 'datatables.instances'])
    .factory('DTRendererService', dtRendererService)
    .factory('DTRenderer', dtRenderer)
    .factory('DTDefaultRenderer', dtDefaultRenderer)
    .factory('DTNGRenderer', dtNGRenderer)
    .factory('DTPromiseRenderer', dtPromiseRenderer)
    .factory('DTAjaxRenderer', dtAjaxRenderer)
    .factory('DTRendererFactory', dtRendererFactory);

/* @ngInject */
function dtRendererService(DTLoadingTemplate) {
    var $loading = angular.element(DTLoadingTemplate.html);
    var plugins = [];
    var rendererService = {
        getLoadingElem: getLoadingElem,
        showLoading: showLoading,
        hideLoading: hideLoading,
        renderDataTable: renderDataTable,
        hideLoadingAndRenderDataTable: hideLoadingAndRenderDataTable,
        registerPlugin: registerPlugin,
        postRender: postRender,
        preRender: preRender
    };
    return rendererService;

    function getLoadingElem() {
        return $loading;
    }

    function showLoading($elem) {
        $elem.after($loading);
        $elem.hide();
        $loading.show();
    }

    function hideLoading($elem) {
        $elem.show();
        $loading.hide();
    }

    function renderDataTable($elem, options) {
        var dtId = '#' + $elem.attr('id');
        if ($.fn.dataTable.isDataTable(dtId) && angular.isObject(options)) {
            options.destroy = true;
        }
        // See http://datatables.net/manual/api#Accessing-the-API to understand the difference between DataTable and dataTable
        var DT = $elem.DataTable(options);
        var dt = $elem.dataTable();

        var result = {
            id: $elem.attr('id'),
            DataTable: DT,
            dataTable: dt
        };

        postRender(options, result);

        return result;
    }

    function hideLoadingAndRenderDataTable($elem, options) {
        rendererService.hideLoading($elem);
        return rendererService.renderDataTable($elem, options);
    }

    function registerPlugin(plugin) {
        plugins.push(plugin);
    }

    function postRender(options, result) {
        angular.forEach(plugins, function(plugin) {
            if (angular.isFunction(plugin.postRender)) {
                plugin.postRender(options, result);
            }
        });
    }

    function preRender(options) {
        angular.forEach(plugins, function(plugin) {
            if (angular.isFunction(plugin.preRender)) {
                plugin.preRender(options);
            }
        });
    }
}
dtRendererService.$inject = ['DTLoadingTemplate'];

function dtRenderer() {
    return {
        withOptions: function(options) {
            this.options = options;
            return this;
        }
    };
}

/* @ngInject */
function dtDefaultRenderer($q, DTRenderer, DTRendererService, DTInstanceFactory) {
    return {
        create: create
    };

    function create(options) {
        var _oTable;
        var _$elem;
        var renderer = Object.create(DTRenderer);
        renderer.name = 'DTDefaultRenderer';
        renderer.options = options;
        renderer.render = render;
        renderer.reloadData = reloadData;
        renderer.changeData = changeData;
        renderer.rerender = rerender;

        function render($elem) {
            _$elem = $elem;
            var dtInstance = DTInstanceFactory.newDTInstance(renderer);
            var result = DTRendererService.hideLoadingAndRenderDataTable($elem, renderer.options);
            _oTable = result.DataTable;
            DTInstanceFactory.copyDTProperties(result, dtInstance);
            return $q.when(dtInstance);
        }

        function reloadData() {
            // Do nothing
        }

        function changeData() {
            // Do nothing
        }

        function rerender() {
            _oTable.destroy();
            DTRendererService.showLoading(_$elem);
            render(_$elem);
        }
        return renderer;
    }
}
dtDefaultRenderer.$inject = ['$q', 'DTRenderer', 'DTRendererService', 'DTInstanceFactory'];

/* @ngInject */
function dtNGRenderer($log, $q, $compile, $timeout, DTRenderer, DTRendererService, DTInstanceFactory) {
    /**
     * Renderer for displaying the Angular way
     * @param options
     * @returns {{options: *}} the renderer
     * @constructor
     */
    return {
        create: create
    };

    function create(options) {
        var _staticHTML;
        var _oTable;
        var _$elem;
        var _parentScope;
        var _newParentScope;
        var dtInstance;
        var renderer = Object.create(DTRenderer);
        renderer.name = 'DTNGRenderer';
        renderer.options = options;
        renderer.render = render;
        renderer.reloadData = reloadData;
        renderer.changeData = changeData;
        renderer.rerender = rerender;
        return renderer;

        function render($elem, $scope, staticHTML) {
            _staticHTML = staticHTML;
            _$elem = $elem;
            _parentScope = $scope.$parent;
            dtInstance = DTInstanceFactory.newDTInstance(renderer);

            var defer = $q.defer();
            var _expression = $elem.find('tbody').html();
            // Find the resources from the comment <!-- ngRepeat: item in items --> displayed by angular in the DOM
            // This regexp is inspired by the one used in the "ngRepeat" directive
            var _match = _expression.match(/^\s*.+?\s+in\s+(\S*)\s*/m);

            if (!_match) {
                throw new Error('Expected expression in form of "_item_ in _collection_[ track by _id_]" but got "{0}".', _expression);
            }
            var _ngRepeatAttr = _match[1];

            var _alreadyRendered = false;

            _parentScope.$watchCollection(_ngRepeatAttr, function() {
                if (_oTable && _alreadyRendered) {
                    _destroyAndCompile();
                }
                $timeout(function() {
                    _alreadyRendered = true;
                    var result = DTRendererService.hideLoadingAndRenderDataTable(_$elem, renderer.options);
                    _oTable = result.DataTable;
                    DTInstanceFactory.copyDTProperties(result, dtInstance);
                    defer.resolve(dtInstance);
                }, 0, false);
            }, true);
            return defer.promise;
        }

        function reloadData() {
            $log.warn('The Angular Renderer does not support reloading data. You need to do it directly on your model');
        }

        function changeData() {
            $log.warn('The Angular Renderer does not support changing the data. You need to change your model directly.');
        }

        function rerender() {
            _destroyAndCompile();
            DTRendererService.showLoading(_$elem);
            $timeout(function() {
                var result = DTRendererService.hideLoadingAndRenderDataTable(_$elem, renderer.options);
                _oTable = result.DataTable;
                DTInstanceFactory.copyDTProperties(result, dtInstance);
            }, 0, false);
        }

        function _destroyAndCompile() {
            if (_newParentScope) {
                _newParentScope.$destroy();
            }
            _oTable.ngDestroy();
            // Re-compile because we lost the angular binding to the existing data
            _$elem.html(_staticHTML);
            _newParentScope = _parentScope.$new();
            $compile(_$elem.contents())(_newParentScope);
        }
    }
}
dtNGRenderer.$inject = ['$log', '$q', '$compile', '$timeout', 'DTRenderer', 'DTRendererService', 'DTInstanceFactory'];

/* @ngInject */
function dtPromiseRenderer($q, $timeout, $log, DTRenderer, DTRendererService, DTInstanceFactory) {
    /**
     * Renderer for displaying with a promise
     * @param options the options
     * @returns {{options: *}} the renderer
     * @constructor
     */
    return {
        create: create
    };

    function create(options) {
        var _oTable;
        var _loadedPromise = null;
        var _$elem;

        var dtInstance;
        var renderer = Object.create(DTRenderer);
        renderer.name = 'DTPromiseRenderer';
        renderer.options = options;
        renderer.render = render;
        renderer.reloadData = reloadData;
        renderer.changeData = changeData;
        renderer.rerender = rerender;
        return renderer;

        function render($elem) {
            var defer = $q.defer();
            dtInstance = DTInstanceFactory.newDTInstance(renderer);
            _$elem = $elem;
            _resolve(renderer.options.fnPromise, DTRendererService.renderDataTable).then(function(result) {
                _oTable = result.DataTable;
                DTInstanceFactory.copyDTProperties(result, dtInstance);
                defer.resolve(dtInstance);
            });
            return defer.promise;
        }

        function reloadData(callback, resetPaging) {
            var previousPage = _oTable && _oTable.page() ? _oTable.page() : 0;
            if (angular.isFunction(renderer.options.fnPromise)) {
                _resolve(renderer.options.fnPromise, _redrawRows).then(function(result) {
                    if (angular.isFunction(callback)) {
                        callback(result.DataTable.data());
                    }
                    if (resetPaging === false) {
                        result.DataTable.page(previousPage).draw(false);
                    }
                });
            } else {
                $log.warn('In order to use the reloadData functionality with a Promise renderer, you need to provide a function that returns a promise.');
            }
        }

        function changeData(fnPromise) {
            renderer.options.fnPromise = fnPromise;
            _resolve(renderer.options.fnPromise, _redrawRows);
        }

        function rerender() {
            _oTable.destroy();
            DTRendererService.showLoading(_$elem);
            render(_$elem);
        }

        function _resolve(fnPromise, callback) {
            var defer = $q.defer();
            if (angular.isUndefined(fnPromise)) {
                throw new Error('You must provide a promise or a function that returns a promise!');
            }
            if (_loadedPromise) {
                _loadedPromise.then(function()  {
                    defer.resolve(_startLoading(fnPromise, callback));
                });
            } else  {
                defer.resolve(_startLoading(fnPromise, callback));
            }
            return defer.promise;
        }

        function _startLoading(fnPromise, callback) {
            var defer = $q.defer();
            if (angular.isFunction(fnPromise)) {
                _loadedPromise = fnPromise();
            } else {
                _loadedPromise = fnPromise;
            }
            _loadedPromise.then(function(result) {
                var data = result;
                // In case the data is nested in an object
                if (renderer.options.sAjaxDataProp) {
                    var properties = renderer.options.sAjaxDataProp.split('.');
                    while (properties.length) {
                        var property = properties.shift();
                        if (property in data) {
                            data = data[property];
                        }
                    }
                }
                _loadedPromise = null;
                defer.resolve(_doRender(renderer.options, _$elem, data, callback));
            });
            return defer.promise;
        }

        function _doRender(options, $elem, data, callback) {
            var defer = $q.defer();
            // Since Angular 1.3, the promise renderer is throwing "Maximum call stack size exceeded"
            // By removing the $promise attribute, we avoid an infinite loop when jquery is cloning the data
            // See https://github.com/l-lin/angular-datatables/issues/110
            delete data.$promise;
            options.aaData = data;
            // Add $timeout to be sure that angular has finished rendering before calling datatables
            $timeout(function() {
                DTRendererService.hideLoading($elem);
                // Set it to true in order to be able to redraw the dataTable
                options.bDestroy = true;
                defer.resolve(callback($elem, options));
            }, 0, false);
            return defer.promise;
        }

        function _redrawRows($elem, options) {
            _oTable.clear();
            _oTable.rows.add(options.aaData).draw(options.redraw);
            return {
                id: dtInstance.id,
                DataTable: dtInstance.DataTable,
                dataTable: dtInstance.dataTable
            };
        }
    }
}
dtPromiseRenderer.$inject = ['$q', '$timeout', '$log', 'DTRenderer', 'DTRendererService', 'DTInstanceFactory'];

/* @ngInject */
function dtAjaxRenderer($q, $timeout, DTRenderer, DTRendererService, DT_DEFAULT_OPTIONS, DTInstanceFactory) {
    /**
     * Renderer for displaying with Ajax
     * @param options the options
     * @returns {{options: *}} the renderer
     * @constructor
     */
    return {
        create: create
    };

    function create(options) {
        var _oTable;
        var _$elem;
        var renderer = Object.create(DTRenderer);
        renderer.name = 'DTAjaxRenderer';
        renderer.options = options;
        renderer.render = render;
        renderer.reloadData = reloadData;
        renderer.changeData = changeData;
        renderer.rerender = rerender;
        return renderer;

        function render($elem) {
            _$elem = $elem;
            var defer = $q.defer();
            var dtInstance = DTInstanceFactory.newDTInstance(renderer);
            // Define default values in case it is an ajax datatables
            if (angular.isUndefined(renderer.options.sAjaxDataProp)) {
                renderer.options.sAjaxDataProp = DT_DEFAULT_OPTIONS.sAjaxDataProp;
            }
            if (angular.isUndefined(renderer.options.aoColumns)) {
                renderer.options.aoColumns = DT_DEFAULT_OPTIONS.aoColumns;
            }
            _doRender(renderer.options, $elem).then(function(result) {
                _oTable = result.DataTable;
                DTInstanceFactory.copyDTProperties(result, dtInstance);
                defer.resolve(dtInstance);
            });
            return defer.promise;
        }

        function reloadData(callback, resetPaging) {
            if (_oTable) {
                _oTable.ajax.reload(callback, resetPaging);
            }
        }

        function changeData(ajax) {
            renderer.options.ajax = ajax;
            if (_oTable) {
                var ajaxUrl = renderer.options.ajax.url ||  renderer.options.ajax;
                _oTable.ajax.url(ajaxUrl).load();
            }
        }

        function rerender() {
            _oTable.destroy();
            DTRendererService.showLoading(_$elem);
            render(_$elem);
        }

        function _doRender(options, $elem) {
                var defer = $q.defer();
                // Set it to true in order to be able to redraw the dataTable
                options.bDestroy = true;
                DTRendererService.hideLoading($elem);
                // Condition to refresh the dataTable
                if (_shouldDeferRender(options)) {
                    $timeout(function() {
                        defer.resolve(DTRendererService.renderDataTable($elem, options));
                    }, 0, false);
                } else {
                    defer.resolve(DTRendererService.renderDataTable($elem, options));
                }
                return defer.promise;
            }
            // See https://github.com/l-lin/angular-datatables/issues/147
        function _shouldDeferRender(options) {
            if (angular.isDefined(options) && angular.isDefined(options.dom)) {
                // S for scroller plugin
                return options.dom.indexOf('S') >= 0;
            }
            return false;
        }
    }
}
dtAjaxRenderer.$inject = ['$q', '$timeout', 'DTRenderer', 'DTRendererService', 'DT_DEFAULT_OPTIONS', 'DTInstanceFactory'];

/* @ngInject */
function dtRendererFactory(DTDefaultRenderer, DTNGRenderer, DTPromiseRenderer, DTAjaxRenderer) {
    return {
        fromOptions: fromOptions
    };

    function fromOptions(options, isNgDisplay)  {
        if (isNgDisplay) {
            return DTNGRenderer.create(options);
        }
        if (angular.isDefined(options)) {
            if (angular.isDefined(options.fnPromise) && options.fnPromise !== null) {
                return DTPromiseRenderer.create(options);
            }
            if (angular.isDefined(options.ajax) && options.ajax !== null ||
                angular.isDefined(options.ajax) && options.ajax !== null) {
                return DTAjaxRenderer.create(options);
            }
            return DTDefaultRenderer.create(options);
        }
        return DTDefaultRenderer.create();
    }
}
dtRendererFactory.$inject = ['DTDefaultRenderer', 'DTNGRenderer', 'DTPromiseRenderer', 'DTAjaxRenderer'];

'use strict';

angular.module('datatables.util', [])
    .factory('DTPropertyUtil', dtPropertyUtil);

/* @ngInject */
function dtPropertyUtil($q) {
    return {
        overrideProperties: overrideProperties,
        deleteProperty: deleteProperty,
        resolveObjectPromises: resolveObjectPromises,
        resolveArrayPromises: resolveArrayPromises
    };

    /**
     * Overrides the source property with the given target properties.
     * Source is not written. It's making a fresh copy of it in order to ensure that we do not change the parameters.
     * @param source the source properties to override
     * @param target the target properties
     * @returns {*} the object overrided
     */
    function overrideProperties(source, target) {
        var result = angular.copy(source);

        if (angular.isUndefined(result) || result === null) {
            result = {};
        }
        if (angular.isUndefined(target) || target === null) {
            return result;
        }
        if (angular.isObject(target)) {
            for (var prop in target) {
                if (target.hasOwnProperty(prop)) {
                    result[prop] = overrideProperties(result[prop], target[prop]);
                }
            }
        } else {
            result = angular.copy(target);
        }
        return result;
    }

    /**
     * Delete the property from the given object
     * @param obj the object
     * @param propertyName the property name
     */
    function deleteProperty(obj, propertyName) {
        if (angular.isObject(obj)) {
            delete obj[propertyName];
        }
    }

    /**
     * Resolve any promises from a given object if there are any.
     * @param obj the object
     * @param excludedPropertiesName the list of properties to ignore
     * @returns {promise} the promise that the object attributes promises are all resolved
     */
    function resolveObjectPromises(obj, excludedPropertiesName) {
        var defer = $q.defer(),
            promises = [],
            resolvedObj = {},
            excludedProp = excludedPropertiesName || [];
        if (!angular.isObject(obj) || angular.isArray(obj)) {
            defer.resolve(obj);
        } else {
            resolvedObj = angular.extend(resolvedObj, obj);
            for (var prop in resolvedObj) {
                if (resolvedObj.hasOwnProperty(prop) && $.inArray(prop, excludedProp) === -1) {
                    if (angular.isArray(resolvedObj[prop])) {
                        promises.push(resolveArrayPromises(resolvedObj[prop]));
                    } else {
                        promises.push($q.when(resolvedObj[prop]));
                    }
                }
            }
            $q.all(promises).then(function(result) {
                var index = 0;
                for (var prop in resolvedObj) {
                    if (resolvedObj.hasOwnProperty(prop) && $.inArray(prop, excludedProp) === -1) {
                        resolvedObj[prop] = result[index++];
                    }
                }
                defer.resolve(resolvedObj);
            });
        }
        return defer.promise;
    }

    /**
     * Resolve the given array promises
     * @param array the array containing promise or not
     * @returns {promise} the promise that the array contains a list of objects/values promises that are resolved
     */
    function resolveArrayPromises(array) {
        var defer = $q.defer(),
            promises = [],
            resolveArray = [];
        if (!angular.isArray(array)) {
            defer.resolve(array);
        } else {
            angular.forEach(array, function(item) {
                if (angular.isObject(item)) {
                    promises.push(resolveObjectPromises(item));
                } else {
                    promises.push($q.when(item));
                }
            });
            $q.all(promises).then(function(result) {
                angular.forEach(result, function(item) {
                    resolveArray.push(item);
                });
                defer.resolve(resolveArray);
            });
        }
        return defer.promise;
    }
}
dtPropertyUtil.$inject = ['$q'];


})(window, document, jQuery, angular);
/*
* File:        jquery.dataTables.columnFilter.js
* Version:     1.5.6.
* Author:      Jovan Popovic
*
* Copyright 2011-2014 Jovan Popovic, all rights reserved.
*
* This source file is free software, under either the GPL v2 license or a
* BSD style license, as supplied with this software.
*
* This source file is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE.
*
* Parameters:"
* @sPlaceHolder                 String      Place where inline filtering function should be placed ("tfoot", "thead:before", "thead:after"). Default is "tfoot"
* @sRangeSeparator              String      Separator that will be used when range values are sent to the server-side. Default value is "~".
* @sRangeFormat                 string      Default format of the From ... to ... range inputs. Default is From {from} to {to}
* @aoColumns                    Array       Array of the filter settings that will be applied on the columns
*/
(function ($) {


    $.fn.columnFilter = function (options) {
        var asInitVals, i, label, th;

        //var sTableId = "table";
        var sRangeFormat = "From {from} to {to}";
        //Array of the functions that will override sSearch_ parameters
        var afnSearch_ = new Array();
        var aiCustomSearch_Indexes = new Array();

        var oFunctionTimeout = null;

        var fnOnFiltered = function () { };

        function _fnGetColumnValues(oSettings, iColumn, bUnique, bFiltered, bIgnoreEmpty) {
            ///<summary>
            ///Return values in the column
            ///</summary>
            ///<param name="oSettings" type="Object">DataTables settings</param>
            ///<param name="iColumn" type="int">Id of the column</param>
            ///<param name="bUnique" type="bool">Return only distinct values</param>
            ///<param name="bFiltered" type="bool">Return values only from the filtered rows</param>
            ///<param name="bIgnoreEmpty" type="bool">Ignore empty cells</param>

            // check that we have a column id
            if (typeof iColumn == "undefined") return new Array();

            // by default we only wany unique data
            if (typeof bUnique == "undefined") bUnique = true;

            // by default we do want to only look at filtered data
            if (typeof bFiltered == "undefined") bFiltered = true;

            // by default we do not wany to include empty values
            if (typeof bIgnoreEmpty == "undefined") bIgnoreEmpty = true;

            // list of rows which we're going to loop through
            var aiRows;

            // use only filtered rows
            if (bFiltered == true) aiRows = oSettings.aiDisplay;
            // use all rows
            else aiRows = oSettings.aiDisplayMaster; // all row numbers

            // set up data array
            var asResultData = new Array();

            for (var i = 0, c = aiRows.length; i < c; i++) {
                var iRow = aiRows[i];
                var aData = oTable.fnGetData(iRow);
                var sValue = aData[iColumn];

                // ignore empty values?
                if (bIgnoreEmpty == true && sValue.length == 0) continue;

                // ignore unique values?
                else if (bUnique == true && jQuery.inArray(sValue, asResultData) > -1) continue;

                // else push the value onto the result data array
                else asResultData.push(sValue);
            }

            return asResultData.sort();
        }

        function _fnColumnIndex(iColumnIndex) {
            if (properties.bUseColVis)
                return iColumnIndex;
            else
                return oTable.fnSettings().oApi._fnVisibleToColumnIndex(oTable.fnSettings(), iColumnIndex);
            //return iColumnIndex;
            //return oTable.fnSettings().oApi._fnColumnIndexToVisible(oTable.fnSettings(), iColumnIndex);
        }

        function fnCreateInput(oTable, regex, smart, bIsNumber, iFilterLength, iMaxLenght) {
            var sCSSClass = "text_filter form-control";
            if (bIsNumber)
                sCSSClass = "number_filter form-control";

            label = label.replace(/(^\s*)|(\s*$)/g, "");
            var currentFilter = oTable.fnSettings().aoPreSearchCols[i].sSearch;
            var search_init = 'search_init ';
            var inputvalue = label;
            if (currentFilter != '' && currentFilter != '^') {
                if (bIsNumber && currentFilter.charAt(0) == '^')
                    inputvalue = currentFilter.substr(1); //ignore trailing ^
                else
                    inputvalue = currentFilter;
                search_init = '';
            }

            var input = $('<input type="text" class="' + search_init + sCSSClass + '" value="' + inputvalue + '" rel="' + i + '"/>');
            if (iMaxLenght != undefined && iMaxLenght != -1) {
                input.attr('maxlength', iMaxLenght);
            }
            th.html(input);
            if (bIsNumber)
                th.wrapInner('<span class="filter_column filter_number" />');
            else
                th.wrapInner('<span class="filter_column filter_text" />');

            asInitVals[i] = label;
            var index = i;

            if (bIsNumber && !oTable.fnSettings().oFeatures.bServerSide) {
                input.keyup(function () {
                    /* Filter on the column all numbers that starts with the entered value */
                    oTable.fnFilter('^' + this.value, _fnColumnIndex(index), true, false); //Issue 37
                    fnOnFiltered();
                });
            } else {
                input.keyup(function () {
                    if (oTable.fnSettings().oFeatures.bServerSide && iFilterLength != 0) {
                        //If filter length is set in the server-side processing mode
                        //Check has the user entered at least iFilterLength new characters

                        var currentFilter = oTable.fnSettings().aoPreSearchCols[index].sSearch;
                        var iLastFilterLength = $(this).data("dt-iLastFilterLength");
                        if (typeof iLastFilterLength == "undefined")
                            iLastFilterLength = 0;
                        var iCurrentFilterLength = this.value.length;
                        if (Math.abs(iCurrentFilterLength - iLastFilterLength) < iFilterLength
                        //&& currentFilter.length == 0 //Why this?
					        ) {
                            //Cancel the filtering
                            return;
                        }
                        else {
                            //Remember the current filter length
                            $(this).data("dt-iLastFilterLength", iCurrentFilterLength);
                        }
                    }
                    /* Filter on the column (the index) of this element */
                    oTable.fnFilter(this.value, _fnColumnIndex(index), regex, smart); //Issue 37
                    fnOnFiltered();
                });
            }

            input.focus(function () {
                if ($(this).hasClass("search_init")) {
                    $(this).removeClass("search_init");
                    this.value = "";
                }
            });
            input.blur(function () {
                if (this.value == "") {
                    $(this).addClass("search_init");
                    this.value = asInitVals[index];
                }
            });
        }

        function fnCreateRangeInput(oTable) {

			//var currentFilter = oTable.fnSettings().aoPreSearchCols[i].sSearch;
            th.html(_fnRangeLabelPart(0));
            var sFromId = oTable.attr("id") + '_range_from_' + i;
            var from = $('<input type="text" class="number_range_filter form-control" id="' + sFromId + '" rel="' + i + '"/>');
            th.append(from);
            th.append(_fnRangeLabelPart(1));
            var sToId = oTable.attr("id") + '_range_to_' + i;
            var to = $('<input type="text" class="number_range_filter form-control" id="' + sToId + '" rel="' + i + '"/>');
            th.append(to);
            th.append(_fnRangeLabelPart(2));
            th.wrapInner('<span class="filter_column filter_number_range form-control" />');
            var index = i;
            aiCustomSearch_Indexes.push(i);



            //------------start range filtering function


            /* 	Custom filtering function which will filter data in column four between two values
            *	Author: 	Allan Jardine, Modified by Jovan Popovic
            */
            //$.fn.dataTableExt.afnFiltering.push(
            oTable.dataTableExt.afnFiltering.push(
	        function (oSettings, aData, iDataIndex) {
	            if (oTable.attr("id") != oSettings.sTableId)
	                return true;
	            // Try to handle missing nodes more gracefully
	            if (document.getElementById(sFromId) == null)
	                return true;
	            var iMin = document.getElementById(sFromId).value * 1;
	            var iMax = document.getElementById(sToId).value * 1;
	            var iValue = aData[_fnColumnIndex(index)] == "-" ? 0 : aData[_fnColumnIndex(index)] * 1;
	            if (iMin == "" && iMax == "") {
	                return true;
	            }
	            else if (iMin == "" && iValue <= iMax) {
	                return true;
	            }
	            else if (iMin <= iValue && "" == iMax) {
	                return true;
	            }
	            else if (iMin <= iValue && iValue <= iMax) {
	                return true;
	            }
	            return false;
	        }
        );
            //------------end range filtering function



            $('#' + sFromId + ',#' + sToId, th).keyup(function () {

                var iMin = document.getElementById(sFromId).value * 1;
                var iMax = document.getElementById(sToId).value * 1;
                if (iMin != 0 && iMax != 0 && iMin > iMax)
                    return;

                oTable.fnDraw();
                fnOnFiltered();
            });


        }


        function fnCreateDateRangeInput(oTable) {

            var aoFragments = sRangeFormat.split(/[}{]/);

            th.html("");
            //th.html(_fnRangeLabelPart(0));
            var sFromId = oTable.attr("id") + '_range_from_' + i;
            var from = $('<input type="text" class="date_range_filter form-control" id="' + sFromId + '" rel="' + i + '"/>');
            from.datepicker();
            //th.append(from);
            //th.append(_fnRangeLabelPart(1));
            var sToId = oTable.attr("id") + '_range_to_' + i;
            var to = $('<input type="text" class="date_range_filter form-control" id="' + sToId + '" rel="' + i + '"/>');
            //th.append(to);
            //th.append(_fnRangeLabelPart(2));

            for (ti = 0; ti < aoFragments.length; ti++) {

                if (aoFragments[ti] == properties.sDateFromToken) {
                    th.append(from);
                } else {
                    if (aoFragments[ti] == properties.sDateToToken) {
                        th.append(to);
                    } else {
                        th.append(aoFragments[ti]);
                    }
                }


            }


            th.wrapInner('<span class="filter_column filter_date_range" />');
            to.datepicker();
            var index = i;
            aiCustomSearch_Indexes.push(i);


            //------------start date range filtering function

            //$.fn.dataTableExt.afnFiltering.push(
            oTable.dataTableExt.afnFiltering.push(
	        function (oSettings, aData, iDataIndex) {
	            if (oTable.attr("id") != oSettings.sTableId)
	                return true;

	            var dStartDate = from.datepicker("getDate");

	            var dEndDate = to.datepicker("getDate");

	            if (dStartDate == null && dEndDate == null) {
	                return true;
	            }

	            var dCellDate = null;
	            try {
	                if (aData[_fnColumnIndex(index)] == null || aData[_fnColumnIndex(index)] == "")
	                    return false;
	                dCellDate = $.datepicker.parseDate($.datepicker.regional[""].dateFormat, aData[_fnColumnIndex(index)]);
	            } catch (ex) {
	                return false;
	            }
	            if (dCellDate == null)
	                return false;


	            if (dStartDate == null && dCellDate <= dEndDate) {
	                return true;
	            }
	            else if (dStartDate <= dCellDate && dEndDate == null) {
	                return true;
	            }
	            else if (dStartDate <= dCellDate && dCellDate <= dEndDate) {
	                return true;
	            }
	            return false;
	        }
        );
            //------------end date range filtering function

            $('#' + sFromId + ',#' + sToId, th).change(function () {
                oTable.fnDraw();
                fnOnFiltered();
            });


        }


        function fnCreateSliderInput(oTable) {
            //var currentFilter = oTable.fnSettings().aoPreSearchCols[i].sSearch;
            //th.html(_fnRangeLabelPart(0));
            th.html("");

            var aoColumn = properties.aoColumns[i],
                input = $('<input>').addClass('number-range'),
                slider_container = $('<div>').addClass("column-slider"),
                slider,
                index = i,
                slider_is_displayed = false,
                slider_info = $('<input>').attr('disabled', 'disabled').hide(),
                formatters = {
                  number: function(x, y) {
                    return x + ' - ' + y
                  },
                  money: function(x, y) {
                    return formatters['number'](Math.floor(x / 100., 2) + ' €', Math.round(y/100., 2) + ' €');
                  }
                },
                formatter = formatters[aoColumn.formatter];

            th.append(input);
            th.append(slider_container);
            th.append(slider_info);
            slider_info.val(formatter(aoColumn.min, aoColumn.max));
            input.val(formatter(aoColumn.min, aoColumn.max));
            slider_container.css({
                position: 'absolute',
                top: '-1000px',
                width: input.css('width'),
                fontSize: input.css('font-size')});
            slider_info.css({
                position: 'absolute',
                top: '-1000px',
                textAlign: 'center',
                width: input.css('width'),
                fontSize: input.css('font-size')});
            slider_container.hide();
            slider = slider_container.slider({
                min: aoColumn.min,
                max: aoColumn.max,
                range: true,
                values: [aoColumn.min, aoColumn.max],
                slide: function(event, ui){
                    var displayed_val = formatter(ui.values[0], ui.values[1]);
                    input.val(displayed_val);
                    slider_info.val(displayed_val);
                }
            });
            input.focus(function(){
                input.css('text-align', 'center');
                slider.css('width',input.css('width')).show();
                slider.position({
                    my: 'center',
                    of: input,
                    at: 'center'
                });
                slider_info.css('width',input.css('width')).show();
                slider_info.position({
                    my: 'bottom',
                    of: slider,
                    at: 'top-10'
                });
                slider_is_displayed = true;
                input.hide();
            });
            $(document).bind("click", function(e){
                if(e.target != input.get(0) && slider_is_displayed){
                    slider.hide();
                    slider_info.hide();
                    slider_is_displayed = false;
                    input.show();
                    oTable.fnFilter(slider.slider('values').join(properties.sRangeSeparator),
                        index, true, false);
                    fnOnFiltered();
                }
            });
        }




        function fnCreateColumnSelect(oTable, aData, iColumn, nTh, sLabel, bRegex, oSelected, bMultiselect) {
            if (aData == null)
                aData = _fnGetColumnValues(oTable.fnSettings(), iColumn, true, false, true);
            var index = iColumn;
            var currentFilter = oTable.fnSettings().aoPreSearchCols[i].sSearch;
            if (currentFilter == null || currentFilter == "")//Issue 81
                currentFilter = oSelected;

            var r = '<select class="search_init select_filter form-control" rel="' + i + '"><option value="" class="search_init">' + sLabel + '</option>';
			if(bMultiselect) {
				r = '<select class="search_init select_filter form-control" rel="' + i + '" multiple>';
			}
            var j = 0;
            var iLen = aData.length;
            for (j = 0; j < iLen; j++) {
                if (typeof (aData[j]) != 'object') {
                    var selected = '';
                    if (escape(aData[j]) == currentFilter
                        || escape(aData[j]) == escape(currentFilter)
                        )
                        selected = 'selected '
                    r += '<option ' + selected + ' value="' + escape(aData[j]) + '">' + aData[j] + '</option>';
                }
                else {
                    var selected = '';
                    if (bRegex) {
                        //Do not escape values if they are explicitely set to avoid escaping special characters in the regexp
                        if (aData[j].value == currentFilter) selected = 'selected ';
                        r += '<option ' + selected + 'value="' + aData[j].value + '">' + aData[j].label + '</option>';
                    } else {
                        if (escape(aData[j].value) == currentFilter) selected = 'selected ';
                        r += '<option ' + selected + 'value="' + escape(aData[j].value) + '">' + aData[j].label + '</option>';
                    }
                }
            }

            var select = $(r + '</select>');
            nTh.html(select);
            nTh.wrapInner('<span class="filter_column filter_select" />');

			if(bMultiselect) {
				select.change(function () {
					if ($(this).val() != "") {
						$(this).removeClass("search_init");
					} else {
						$(this).addClass("search_init");
					}
					var selectedOptions = $(this).val();
					var asEscapedFilters = [];
					if(selectedOptions==null || selectedOptions==[]){
						var re = '^(.*)$';
					}else{
						$.each( selectedOptions, function( i, sFilter ) {
							asEscapedFilters.push( fnRegExpEscape( sFilter ) );
						} );
						var re = '^(' + asEscapedFilters.join('|') + ')$';
					}

					oTable.fnFilter( re, index, true, false );
				});
			} else {
				select.change(function () {
					//var val = $(this).val();
					if ($(this).val() != "") {
						$(this).removeClass("search_init");
					} else {
						$(this).addClass("search_init");
					}
					if (bRegex)
						oTable.fnFilter($(this).val(), iColumn, bRegex); //Issue 41
					else
						oTable.fnFilter(unescape($(this).val()), iColumn); //Issue 25
					fnOnFiltered();
				});
				if (currentFilter != null && currentFilter != "")//Issue 81
					oTable.fnFilter(unescape(currentFilter), iColumn);
			}
        }

        function fnCreateSelect(oTable, aData, bRegex, oSelected, bMultiselect) {
            var oSettings = oTable.fnSettings();
            if ( (aData == null || typeof(aData) == 'function' ) && oSettings.sAjaxSource != "" && !oSettings.oFeatures.bServerSide) {
                // Add a function to the draw callback, which will check for the Ajax data having
                // been loaded. Use a closure for the individual column elements that are used to
                // built the column filter, since 'i' and 'th' (etc) are locally "global".
                oSettings.aoDrawCallback.push({
                    "fn": (function (iColumn, nTh, sLabel) {
                        return function (oSettings) {
                            // Only rebuild the select on the second draw - i.e. when the Ajax
                            // data has been loaded.
                            if (oSettings.iDraw == 2 && oSettings.sAjaxSource != null && oSettings.sAjaxSource != "" && !oSettings.oFeatures.bServerSide) {
                                return fnCreateColumnSelect(oTable, aData && aData(oSettings.aoData, oSettings), _fnColumnIndex(iColumn), nTh, sLabel, bRegex, oSelected, bMultiselect); //Issue 37
                            }
                        };
                    })(i, th, label),
                    "sName": "column_filter_" + i
                });
            }
            // Regardless of the Ajax state, build the select on first pass
            fnCreateColumnSelect(oTable, typeof(aData) == 'function' ? null: aData, _fnColumnIndex(i), th, label, bRegex, oSelected, bMultiselect); //Issue 37

        }

		function fnRegExpEscape( sText ) {
			return sText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
		};

		function fnCreateDropdown(aData) {
			var index = i;
			var r = '<div class="dropdown select_filter form-control"><a class="dropdown-toggle" data-toggle="dropdown" href="#">' + label + '<b class="caret"></b></a><ul class="dropdown-menu" role="menu"><li data-value=""><a>Show All</a></li>', j, iLen = aData.length;

			for (j = 0; j < iLen; j++) {
				r += '<li data-value="' + aData[j] + '"><a>' + aData[j] + '</a></li>';
			}
			var select = $(r + '</ul></div>');
			th.html(select);
			th.wrapInner('<span class="filterColumn filter_select" />');
			select.find('li').click(function () {
				oTable.fnFilter($(this).data('value'), index);
			});
		}


        function fnCreateCheckbox(oTable, aData) {

            if (aData == null)
                aData = _fnGetColumnValues(oTable.fnSettings(), i, true, true, true);
            var index = i;

            var r = '', j, iLen = aData.length;

            //clean the string
            var localLabel = label.replace('%', 'Perc').replace("&", "AND").replace("$", "DOL").replace("£", "STERL").replace("@", "AT").replace(/\s/g, "_");
            localLabel = localLabel.replace(/[^a-zA-Z 0-9]+/g, '');
            //clean the string

            //button label override
            var labelBtn = label;
            if (properties.sFilterButtonText != null || properties.sFilterButtonText != undefined) {
                labelBtn = properties.sFilterButtonText;
            }

            var relativeDivWidthToggleSize = 10;
            var numRow = 12; //numero di checkbox per colonna
            var numCol = Math.floor(iLen / numRow);
            if (iLen % numRow > 0) {
                numCol = numCol + 1;
            };

            //count how many column should be generated and split the div size
            var divWidth = 100 / numCol - 2;

            var divWidthToggle = relativeDivWidthToggleSize * numCol;

            if (numCol == 1) {
                divWidth = 20;
            }

            var divRowDef = '<div style="float:left; min-width: ' + divWidth + '%; " >';
            var divClose = '</div>';

            var uniqueId = oTable.attr("id") + localLabel;
            var buttonId = "chkBtnOpen" + uniqueId;
            var checkToggleDiv = uniqueId + "-flt-toggle";
            r += '<button id="' + buttonId + '" class="checkbox_filter btn btn-default" > ' + labelBtn + '</button>'; //filter button witch open dialog
            r += '<div id="' + checkToggleDiv + '" '
            	+ 'title="' + label + '" '
                + 'rel="' + i + '" '
            	+ 'class="toggle-check ui-widget-content ui-corner-all"  style="width: ' + (divWidthToggle) + '%; " >'; //dialog div
            //r+= '<div align="center" style="margin-top: 5px; "> <button id="'+buttonId+'Reset" class="checkbox_filter" > reset </button> </div>'; //reset button and its div
            r += divRowDef;

            for (j = 0; j < iLen; j++) {

                //if last check close div
                if (j % numRow == 0 && j != 0) {
                    r += divClose + divRowDef;
                }

                var sLabel = aData[j];
                var sValue = aData[j];

                if (typeof (aData[j]) == 'object') {
                    sLabel = aData[j].label;
                    sValue = aData[j].value;
                }

                //check button
                r += '<input class="search_init checkbox_filter btn btn-default" type="checkbox" id= "' + uniqueId + '_cb_' + sValue + '" name= "' + localLabel + '" value="' + sValue + '" >' + sLabel + '<br/>';

                var checkbox = $(r);
                th.html(checkbox);
                th.wrapInner('<span class="filter_column filter_checkbox" />');
                //on every checkbox selection
                checkbox.change(function () {

                    var search = '';
                    var or = '|'; //var for select checks in 'or' into the regex
                    var resSize = $('input:checkbox[name="' + localLabel + '"]:checked').size();
                    $('input:checkbox[name="' + localLabel + '"]:checked').each(function (index) {

                        //search = search + ' ' + $(this).val();
                        //concatenation for selected checks in or
                        if ((index == 0 && resSize == 1)
                				|| (index != 0 && index == resSize - 1)) {
                            or = '';
                        }
                        //trim
                        search = search.replace(/^\s+|\s+$/g, "");
                        search = search + $(this).val() + or;
                        or = '|';

                    });


                    if (search != "") {
                        $('input:checkbox[name="' + localLabel + '"]').removeClass("search_init");
                    } else {
                        $('input:checkbox[name="' + localLabel + '"]').addClass("search_init");
                    }
                    /* Old code for setting search_init CSS class on checkboxes if any of them is checked
                    for (var jj = 0; jj < iLen; jj++) {
                        if (search != "") {
                            $('#' + aData[jj]).removeClass("search_init");
                        } else {
                            $('#' + aData[jj]).addClass("search_init");
                        }
                    }
                    */

                    //execute search
                    oTable.fnFilter(search, index, true, false);
                    fnOnFiltered();
                });
            }

            //filter button
            $('#' + buttonId).button();
            //dialog
            $('#' + checkToggleDiv).dialog({
                //height: 140,
                autoOpen: false,
                //show: "blind",
                hide: "blind",
                buttons: [{
                    text: "Reset",
                    click: function () {
                        //$('#'+buttonId).removeClass("filter_selected"); //LM remove border if filter selected
                        $('input:checkbox[name="' + localLabel + '"]:checked').each(function (index3) {
                            $(this).attr('checked', false);
                            $(this).addClass("search_init");
                        });
                        oTable.fnFilter('', index, true, false);
                        fnOnFiltered();
                        return false;
                    }
                },
							{
							    text: "Close",
							    click: function () { $(this).dialog("close"); }
							}
						]
            });


            $('#' + buttonId).click(function () {

                $('#' + checkToggleDiv).dialog('open');
                var target = $(this);
                $('#' + checkToggleDiv).dialog("widget").position({ my: 'top',
                    at: 'bottom',
                    of: target
                });

                return false;
            });

            var fnOnFilteredCurrent = fnOnFiltered;

            fnOnFiltered = function () {
                var target = $('#' + buttonId);
                $('#' + checkToggleDiv).dialog("widget").position({ my: 'top',
                    at: 'bottom',
                    of: target
                });
                fnOnFilteredCurrent();
            };
            //reset
            /*
            $('#'+buttonId+"Reset").button();
            $('#'+buttonId+"Reset").click(function(){
            $('#'+buttonId).removeClass("filter_selected"); //LM remove border if filter selected
            $('input:checkbox[name="'+localLabel+'"]:checked').each(function(index3) {
            $(this).attr('checked', false);
            $(this).addClass("search_init");
            });
            oTable.fnFilter('', index, true, false);
            return false;
            });
            */
        }




        function _fnRangeLabelPart(iPlace) {
            switch (iPlace) {
                case 0:
                    return sRangeFormat.substring(0, sRangeFormat.indexOf("{from}"));
                case 1:
                    return sRangeFormat.substring(sRangeFormat.indexOf("{from}") + 6, sRangeFormat.indexOf("{to}"));
                default:
                    return sRangeFormat.substring(sRangeFormat.indexOf("{to}") + 4);
            }
        }




        var oTable = this;

        var defaults = {
            sPlaceHolder: "foot",
            sRangeSeparator: "~",
            iFilteringDelay: 500,
            aoColumns: null,
            sRangeFormat: "From {from} to {to}",
            sDateFromToken: "from",
            sDateToToken: "to"
        };

        var properties = $.extend(defaults, options);

        return this.each(function () {

            if (!oTable.fnSettings().oFeatures.bFilter)
                return;
            asInitVals = new Array();

            var aoFilterCells = oTable.fnSettings().aoFooter[0];

            var oHost = oTable.fnSettings().nTFoot; //Before fix for ColVis
            var sFilterRow = "tr"; //Before fix for ColVis

            if (properties.sPlaceHolder == "head:after") {
                var tr = $("tr:first", oTable.fnSettings().nTHead).detach();
                //tr.appendTo($(oTable.fnSettings().nTHead));
                if (oTable.fnSettings().bSortCellsTop) {
                    tr.prependTo($(oTable.fnSettings().nTHead));
                    //tr.appendTo($("thead", oTable));
                    aoFilterCells = oTable.fnSettings().aoHeader[1];
                }
                else {
                    tr.appendTo($(oTable.fnSettings().nTHead));
                    //tr.prependTo($("thead", oTable));
                    aoFilterCells = oTable.fnSettings().aoHeader[0];
                }

                sFilterRow = "tr:last";
                oHost = oTable.fnSettings().nTHead;

            } else if (properties.sPlaceHolder == "head:before") {

                if (oTable.fnSettings().bSortCellsTop) {
                    var tr = $("tr:first", oTable.fnSettings().nTHead).detach();
                    tr.appendTo($(oTable.fnSettings().nTHead));
                    aoFilterCells = oTable.fnSettings().aoHeader[1];
                } else {
                    aoFilterCells = oTable.fnSettings().aoHeader[0];
                }
                /*else {
                //tr.prependTo($("thead", oTable));
                sFilterRow = "tr:first";
                }*/

                sFilterRow = "tr:first";

                oHost = oTable.fnSettings().nTHead;


            }

            //$(sFilterRow + " th", oHost).each(function (index) {//bug with ColVis
            $(aoFilterCells).each(function (index) {//fix for ColVis
                i = index;
                var aoColumn = { type: "text",
                    bRegex: false,
                    bSmart: true,
                    iMaxLenght: -1,
                    iFilterLength: 0
                };
                if (properties.aoColumns != null) {
                    if (properties.aoColumns.length < i || properties.aoColumns[i] == null)
                        return;
                    aoColumn = properties.aoColumns[i];
                }
                //label = $(this).text(); //Before fix for ColVis
                label = $($(this)[0].cell).text(); //Fix for ColVis
                if (aoColumn.sSelector == null) {
                    //th = $($(this)[0]);//Before fix for ColVis
                    th = $($(this)[0].cell); //Fix for ColVis
                }
                else {
                    th = $(aoColumn.sSelector);
                    if (th.length == 0)
                        th = $($(this)[0].cell);
                }

                if (aoColumn != null) {
                    if (aoColumn.sRangeFormat != null)
                        sRangeFormat = aoColumn.sRangeFormat;
                    else
                        sRangeFormat = properties.sRangeFormat;
                    switch (aoColumn.type) {
                        case "null":
                            break;
                        case "number":
                            fnCreateInput(oTable, true, false, true, aoColumn.iFilterLength, aoColumn.iMaxLenght);
                            break;
                        case "select":
                            if (aoColumn.bRegex != true)
                                aoColumn.bRegex = false;
                            fnCreateSelect(oTable, aoColumn.values, aoColumn.bRegex, aoColumn.selected, aoColumn.multiple);
                            break;
                        case "number-range":
                            fnCreateRangeInput(oTable);
                            break;
                        case "date-range":
                            fnCreateDateRangeInput(oTable);
                            break;
                        case "slider":
                            fnCreateSliderInput(oTable);
                            break;
                        case "checkbox":
                            fnCreateCheckbox(oTable, aoColumn.values);
                            break;
						case "twitter-dropdown":
						case "dropdown":
                            fnCreateDropdown(aoColumn.values);
                            break;
                        case "text":
                        default:
                            bRegex = (aoColumn.bRegex == null ? false : aoColumn.bRegex);
                            bSmart = (aoColumn.bSmart == null ? false : aoColumn.bSmart);
                            fnCreateInput(oTable, bRegex, bSmart, false, aoColumn.iFilterLength, aoColumn.iMaxLenght);
                            break;

                    }
                }
            });

            for (j = 0; j < aiCustomSearch_Indexes.length; j++) {
                //var index = aiCustomSearch_Indexes[j];
                var fnSearch_ = function () {
                    var id = oTable.attr("id");
                    return $("#" + id + "_range_from_" + aiCustomSearch_Indexes[j]).val() + properties.sRangeSeparator + $("#" + id + "_range_to_" + aiCustomSearch_Indexes[j]).val()
                }
                afnSearch_.push(fnSearch_);
            }

            if (oTable.fnSettings().oFeatures.bServerSide) {

                var fnServerDataOriginal = oTable.fnSettings().fnServerData;

                oTable.fnSettings().fnServerData = function (sSource, aoData, fnCallback) {

                    for (j = 0; j < aiCustomSearch_Indexes.length; j++) {
                        var index = aiCustomSearch_Indexes[j];

                        for (k = 0; k < aoData.length; k++) {
                            if (aoData[k].name == "sSearch_" + index)
                                aoData[k].value = afnSearch_[j]();
                        }
                    }
                    aoData.push({ "name": "sRangeSeparator", "value": properties.sRangeSeparator });

                    if (fnServerDataOriginal != null) {
                        try {
                            fnServerDataOriginal(sSource, aoData, fnCallback, oTable.fnSettings()); //TODO: See Issue 18
                        } catch (ex) {
                            fnServerDataOriginal(sSource, aoData, fnCallback);
                        }
                    }
                    else {
                        $.getJSON(sSource, aoData, function (json) {
                            fnCallback(json)
                        });
                    }
                };

            }

        });

    };




})(jQuery);
/*global $, jQuery, exFilterColumn, exGetColumnFilterVal, saveStateSave, moment*/
/*jslint plusplus: true, nomen: true, eqeq: true */
/*!
* Yet Another DataTables Column Filter - (yadcf)
*
* File:        jquery.dataTables.yadcf.js
* Version:     0.8.9.beta.14 (grab latest stable from https://github.com/vedmack/yadcf/releases)
*
* Author:      Daniel Reznick
* Info:        https://github.com/vedmack/yadcf
* Contact:     vedmack@gmail.com
* Twitter:	   @danielreznick
* Q&A		   http://stackoverflow.com/questions/tagged/yadcf
*
* Copyright 2015 Daniel Reznick, all rights reserved.
* Copyright 2015 Released under the MIT License
*
* This source file is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.
*/
/*
* Parameters:
*
*
* -------------

* column_number
				Required:			true
				Type:				int
				Description:		The number of the column to which the filter will be applied

* filter_type
				Required:			false
				Type:				String
				Default value:		select
				Possible values:	select / multi_select / auto_complete / text / date / range_number / range_number_slider / range_date / custom_func / multi_select_custom_func
				Description:		The type of the filter to be used in the column

* custom_func
				Required:			true (when filter_type is custom_func / multi_select_custom_func)
				Type:				function
				Default value:		undefined
				Description:		should be pointing to a function with the following signature myCustomFilterFunction(filterVal, columnVal, rowValues) , where filterVal is the value from the select box and
									columnVal is the value from the relevant row column, rowValues is an array that holds the values of the entire row, this function should return true if the row matches your condition and the row should be displayed) and false otherwise
				Note:				When using multi_select_custom_func as filter_type filterVal will hold an array of selected values from the multi select element

* data
				Required:			false
				Type:				Array (of string or objects)
				Description:		When the need of predefined data for filter is needed just use an array of strings ["value1","value2"....] (supported in select / multi_select / auto_complete filters) or
									array of objects [{value: 'Some Data 1', label: 'One'}, {value: 'Some Data 3', label: 'Three'}] (supported in select / multi_select filters)
				Note:				that when filter_type is custom_func / multi_select_custom_func this array will populate the custom filter select element

* append_data_to_table_data
				Required:			false
				Type:				string
				Default value:		undefined
				Possible values:	before / sorted
				Description:		Use 'before' to place your data array before the values that yadcf grabs from the table
									use 'sorted' to place the data array sorted along with the values that yadcf grabs from the table
				Note:				'sorted' option will have affect only if you data is an array of primitives (not objects)

* column_data_type
				Required:			false
				Type:				String
				Default value:		text
				Possible values:	text / html	/ rendered_html
				Description:		The type of data in column , use "html" when you have some html code in the column (support parsing of multiple elements per cell),
									use rendered_html when you are using render function of columnDefs or similar, that produces a html code, note that both types rendered_html and html have a fallback for simple text parsing

* text_data_delimiter
				Required:			false
				Type:				String
				Description:		Delimiter that seperates text in table column, for example text_data_delimiter: ","

* html_data_type
				Required:			false
				Type:				String
				Default value:		text
				Possible values:	text / value / id / selector
				Description:		When using "html" for column_data_type argument you can choose how exactly to parse your html element/s in column , for example use "text" for the following <span class="someClass">Some text</span>
				Special notes:		when using selector you must provide a valid selector string for the html_data_selector property

* html_data_selector
				Required:			false
				Type:				String
				Default value:		undefined
				Possible values:	any valid selector string, for example 'li:eq(1)'
				Description:		allows for advanced text value selection within the html located in the td element
				Special notes:		know that the selector string "begin is search" from (and not outside) the first element of the html inside the td
									(supported by range_number_slider / select / auto_complete)

* html5_data
				Required:			false
				Type:				String
				Default value:		undefined
				Possible values:	data-filter / data-search / anything that is supported by datatables
				Description:		Allows to filter based on data-filter / data-search attributes of the <td> element, read more: http://www.datatables.net/examples/advanced_init/html5-data-attributes.html

* filter_container_id
				Required:			false
				Type:				String
				Description:		In case that user don't want to place the filter in column header , he can pass an id of the desired container for the column filter

* filter_default_label
				Required:			false
				Type:				String / Array of string in case of range_number filter (first entry is for the first input and the second entry is for the second input
				Default value:		Select value
				Description:		The label that will appear in the select menu filter when no value is selected from the filter

* filter_reset_button_text
				Required:			false
				Type:				String / boolean
				Default value:		x
				Description:		The text that will appear inside the reset button next to the select drop down (set this to false (boolean) in order to hide it from that column filter)

* enable_auto_complete (this attribute is deprecated , and will become obsolete in the future , so you better start using filter_type: "auto_complete")
				Required:			false
				Type:				boolean
				Default value:		false
				Description:		Turns the filter into an autocomplete input - make use of the jQuery UI Autocomplete widget (with some enhancements)

* sort_as
				Required:			false
				Type:				String
				Default value:		alpha
				Possible values:	alpha / num / alphaNum / none
				Description:		Defines how the values in the filter will be sorted, alphabetically / numerically / alphanumeric / custom / not sorted at all (none is useful to preserve
									the order of the data attribute as is)
				Note:				When custom value is set you must provide a custom sorting function for the sort_as_custom_func property

* sort_as_custom_func
				Required:			false
				Type:				function
				Default value:		undefined
				Description:		Allows to provide a custom sorting function for the filter elements

* sort_order
				Required:			false
				Type:				String
				Default value:		asc
				Possible values:	asc / desc
				Description:		Defines the order in which the values in the filter will be sorted, ascending or descending

* date_format
				Required:			false
				Type:				String
				Default value:		mm/dd/yyyy
				Possible values:	mm/dd/yyyy / dd/mm/yyyy
				Description:		Defines the format in which the date values are being parsed into Date object
				Note:				You can replace the / separator with other one , for example mm-dd-yy

* ignore_char
				Required:			false
				Type:				String
				Description:		Tells the range_number and range_number_slide to ignore specific char while filtering (that char can used as number separator)
				Note:				Use double escape for regex chars , e.g \\$ , also you can use multiple ignore chars with | , e.g '_|\\.|\\$'

* filter_match_mode
				Required:			false
				Type:				String
				Default value:		contains
				Possible values:	contains / exact / startsWith / regex
				Description:		Allows to control the matching mode of the filter (supported in select / auto_complete / text filters)

* exclude
				Required:			false
				Type:				boolean
				Default value:		undefined
				Description:		Adds a checkbox next to the filter that allows to do a "not/exclude" filtering (acts the same  all filter_match_mode)
				Note:				Currently available for the text filter

* exclude_label
				Required:			false
				Type:				string
				Default value:		exclude
				Description:		The label that will appear above the exclude checkbox

* select_type
				Required:			false
				Type:				String
				Default value:		undefined
				Possible values:	chosen / select2 / custom_select
				Description:		Turns the simple select element into Chosen / Select2 (make use of the Chosen / Select2 select jQuery plugins)
				Note:				When using custom_select , make sure to call the initSelectPluginCustomTriggers,
									before calling yadcf constructor / init function

* select_type_options
				Required:			false
				Type:				Object
				Default value:		{}
				Description:		This parameter will be passed "as is" to the Chosen/Select2 plugin constructor

* filter_plugin_options
				Required:			false
				Type:				Object
				Default value:		undefined
				Description:		This parameter will be passed to the jQuery Autocomplete / jQuery Slider / Bootstrap Datetimepicker

* case_insensitive
				Required:			false
				Type:				boolean
				Default value:		true
				Description:		Do case-insensitive filtering (supported in select / auto_complete / text filters)


* filter_delay
				Required:			false
				Type:				integer
				Default value:		undefined
				Description:		Delay filter execution for a XXX milliseconds - filter will fire XXX milliseconds after the last keyup.
				Special notes:		Currently supported in text / range_number / range_date filters / range_number_slider

* datepicker_type
                Required:			false
				Type:				string
				Default value:		'jquery-ui'
				Possible values:    'jquery-ui', 'bootstrap-datetimepicker', 'bootstrap-datepicker'
				Description:		You can choose datapicker library from defined in special notes
				Special notes:		Currently supported only jQueryUI datepicker (datepicker) and Bootstrap datepicker (eonasdan-bootstrap-datetimepicker)
				                    Bootstrap datepicker depends moment library. This plugin depends moment too.

* Global Parameters (per table rather than per column)
*
* Usage example yadcf.init(oTable,[{column_number : 0}, {column_number: 3}],{cumulative_filtering: true});
* -------------

* externally_triggered
                Required:			false
				Type:				boolean
				Default value:		false
				Description:		Filters will filter only when yadcf.exFilterExternallyTriggered(table_arg) is called
				Special notes:		Useful when you want to build some form with filters and you want to trigger the filter when that form
									"submit" button is clicked (instead of filtering per filter input change)

* cumulative_filtering
                Required:			false
				Type:				boolean
				Default value:		false
				Description:		Change the default behaviour of the filters so its options will be populated from the filtered rows (remaining
									table data after filtering) only unlike the normal behaviour in which the options of the filters are from all the table data
				Special notes:		Useful when you want to build some form with filters and you want to trigger the filter when that form
									"submit" button is clicked (instead of filtering per filter input change)


*
*
*
*
* External API functions:
*
*
* -------------

* exFilterColumn
				Description:		Allows to trigger filter/s externally/programmatically (support ALL filter types!!!) , perfect for showing table with pre filtered columns
				Arguments:			table_arg: (variable of the datatable),
									array of pairs: column number String/Object with from and to, filter_value (the actual string value that we want to filter by)
				Usage example:		yadcf.exFilterColumn(oTable, [[0, 'Some Data 2']]); //pre filter one column
									yadcf.exFilterColumn(oTable, [[0, 'Some Data 1'], [1, {from: 111, to: 1110}], [2, {from: "", to: "11/25/2014"}]]); //pre filter several columns
									yadcf.exFilterColumn(oTable, [[0, ['Some Data 1','Some Data 2']]]); // for pre filtering multi select filter you should use array with values (or an array with single value)

* exGetColumnFilterVal
				Description:		Allows to retrieve  column current filtered value (support ALL filter types!!!)
				Arguments:			table_arg: (variable of the datatable),
									column number:  column number from which we want the value
				Usage example:		yadcf.exGetColumnFilterVal(oTable,1);
				Return value:		String (for simple filter) / Object (for range filter) with from and to properties / Array of strings for multi_select filter


* exResetAllFilters
				Description:		Allows to reset all filters externally/programmatically (support ALL filter types!!!) , perfect for adding a "reset all" button to your page!
				Arguments:			table_arg: (variable of the datatable)
									noRedraw:	(boolean) , use it if you don't want your table to be reloaded after the filter reset,
												for example if you planning to call exFilterColumn function right after the exResetAllFilters (to avoid two AJAX requests)
				Usage example:		yadcf.exResetAllFilters(oTable);

* exResetFilters
				Description:		Allows to reset specific filters externally/programmatically (support ALL filter types!!!) , can be used for resetting one or more filters
				Arguments:			table_arg: (variable of the datatable)
									array with columns numbers
				Usage example:		yadcf.exResetAllFilters(oTable, [1,2]);

* initSelectPluginCustomTriggers
				Description:		Allows to set any select jquery plugin initialize and refresh functions. jQuery selector will be passed to the user defined function to initialize and refresh the plugin.
									Great for integrating any jquey select plugin  (Selectize / MultiSelect / etc)
				Arguments:			initFunc  : function which will initialize the plugin
									refreshFunc : function that will refresh the plugin.
				Usage example:		yadcf.initSelectPluginCustomTriggers(function($filterSelector){$filterSelector.multiselect({});}, function($filterSelector){$filterSelector.multiselect("refresh")});

* exFilterExternallyTriggered
				Description:		Triggers all the available filters, should be used only when the externally_triggered option used
				Arguments:			table_arg: (variable of the datatable)
				Usage example:		yadcf.exResetAllFilters(table_arg);
*
*
*
* Server-side processing API (see more on showcase):
*
* From server to client:
* In order to populate the filters with data from server (select / auto_complete / range_number_slider (min and max values), you should add to your current json respond the following properties:
* lets say for first column you add yadcf_data_0 filled with array of values, for column second column yadcf_data_1 and so on...
*
* From client to server:
* Read the filtered value like this (for first column) req.getParameter("columns[0][search][value]"); <- java code , php/.Net/etc you just need to get it from the request
* Range filter value will arrive delimited by  -yadcf_delim- , so just split it into an array or something like this: String[] minMax = sSearch_0.split("-yadcf_delim-");
*
*
* Filters position
*
*
* -------------

* Filters can be placed in the header (thead) or in the footer (tfoot) , it is defined by the second argument of yadcf constructor
  or third argument of init function. Header location is the default position, use 'footer' in order to place the filters in the tfoot position


*
*
*
* Working with filters for multiple tables:
*
*
* -------------

* initMultipleTables
				Description:		Allows to create filter that will affect multiple tables / multiple column(s) in multiple tables
				Arguments:			Array of tables,
									Array of objects with properties for each filter
				Usage example:		yadcf.initMultipleTables([oTable, oTable2], [{
										column_number: [0, 1], filter_container_id: 'multi-table-filter-0', filter_default_label: 'Filter all tables columns 1 and 2!'
									},
									{
										column_number: [2], filter_container_id: 'multi-table-filter-1', filter_default_label: 'Filter all tables column 3!'
									}]);
				Valid properties:	filter_type: 'text' (default) / 'select',
									column_number: not required (in that case the filter will be global)
												   can be either number(single column filter) or array of numbers(multiple columns filter)
									filter_container_id: '' (required),
				Note:				All the usual properties of yadcf should be supported in initMultipleTables too!

* initMultipleColumns
				Description:		Allows to create filter that will affect multiple column(s) in in a particular table
				Arguments:			Table variable,
									Array of objects with properties for each filter
				Usage example:		yadcf.initMultipleColumns(oTable, [{
										column_number: [0, 1], filter_container_id: 'multi-table-filter-0', filter_default_label: 'Filter columns 1 and 2!'
									},
									{
										column_number: [2, 3], filter_container_id: 'multi-table-filter-1', filter_default_label: 'Filter column 3 and 4!'
									}]);
				Valid properties:	filter_type: 'text' (default) / 'select',
									column_number: not required (in that case the filter will be global)
												   can be either number(single column filter) or array of numbers(multiple columns filter)
									filter_container_id: '' (required),
				Note:				All the usual properties of yadcf should be supported in initMultipleColumns too!
*/
var yadcf = (function ($) {

  
	'use strict';

	var tablesDT = {},
		oTables = {},
		oTablesIndex = {},
		options = {},
		plugins = {},
		exFilterColumnQueue = [],
		yadcfDelay,
		reA = /[^a-zA-Z]/g,
		reN = /[^0-9]/g,
		selectElementCustomInitFunc,
		selectElementCustomRefreshFunc;

	//From ColReorder (SpryMedia Ltd (www.sprymedia.co.uk))
	function getSettingsObjFromTable(dt) {
		var oDTSettings;
		if ($.fn.dataTable.Api) {
			oDTSettings = new $.fn.dataTable.Api(dt).settings()[0];
		} else if (dt.fnSettings) {// 1.9 compatibility
			// DataTables object, convert to the settings object
			oDTSettings = dt.fnSettings();
		} else if (typeof dt === 'string') {// jQuery selector
			if ($.fn.dataTable.fnIsDataTable($(dt)[0])) {
				oDTSettings = $(dt).eq(0).dataTable().fnSettings();
			}
		} else if (dt.nodeName && dt.nodeName.toLowerCase() === 'table') {
			// Table node
			if ($.fn.dataTable.fnIsDataTable(dt.nodeName)) {
				oDTSettings = $(dt.nodeName).dataTable().fnSettings();
			}
		} else if (dt instanceof jQuery) {
			// jQuery object
			if ($.fn.dataTable.fnIsDataTable(dt[0])) {
				oDTSettings = dt.eq(0).dataTable().fnSettings();
			}
		} else {
			// DataTables settings object
			oDTSettings = dt;
		}
		return oDTSettings;
	}

	function arraySwapValueWithIndex(pArray) {
		var tmp = [],
			i;
		for (i = 0; i < pArray.length; i++) {
			tmp[pArray[i]] = i;
		}
		return tmp;
	}

	function arraySwapValueWithIndex2(pArray) {
		var tmp = [],
			i;
		for (i = 0; i < pArray.length; i++) {
			tmp[pArray[i]._ColReorder_iOrigCol] = i;
		}
		return tmp;
	}

	function initColReorder2(settingsDt, table_selector_jq_friendly) {
		if (settingsDt.oSavedState != undefined && settingsDt.oSavedState.ColReorder !== undefined) {
			if (plugins[table_selector_jq_friendly] === undefined) {
				plugins[table_selector_jq_friendly] = {};
				plugins[table_selector_jq_friendly].ColReorder = arraySwapValueWithIndex(settingsDt.oSavedState.ColReorder);
			}
		} else if (settingsDt.aoColumns[0]._ColReorder_iOrigCol !== undefined) {
			if (plugins[table_selector_jq_friendly] === undefined) {
				plugins[table_selector_jq_friendly] = {};
				plugins[table_selector_jq_friendly].ColReorder = arraySwapValueWithIndex2(settingsDt.aoColumns);
			}
		}
	}

	function initColReorderFromEvent(table_selector_jq_friendly) {
		plugins[table_selector_jq_friendly] = undefined;
	}

	function columnsArrayToString(column_number) {
		var column_number_obj = {};
		if (column_number !== undefined) {
			if (column_number instanceof Array) {
				column_number_obj.column_number_str = column_number.join('_');
			} else {
				column_number_obj.column_number_str = column_number;
				column_number = [];
				column_number.push(column_number_obj.column_number_str);
			}
		} else {
			column_number_obj.column_number_str = 'global';
		}
		column_number_obj.column_number = column_number;
		return column_number_obj;
	}

	function getOptions(selector) {
		return options[selector];
	}

	function eventTargetFixUp(pEvent) {
		if (pEvent.target === undefined) {
            pEvent.target = pEvent.srcElement;
        }
		return pEvent;
	}

	function dot2obj(tmpObj, dot_refs) {
		var i = 0;
		dot_refs = dot_refs.split(".");
		for (i = 0; i < dot_refs.length; i++) {
			tmpObj = tmpObj[dot_refs[i]];
		}
		return tmpObj;
	}

	function setOptions(selector_arg, options_arg, params) {
		var tmpOptions = {},
			i,
			j,
			col_num_as_int,
			default_options = {
				filter_type : "select",
				enable_auto_complete : false,
				sort_as : "alpha",
				sort_order : "asc",
				date_format : "mm/dd/yyyy",
				ignore_char : undefined,
				filter_match_mode : "contains",
				select_type : undefined,
				select_type_options : {},
				case_insensitive : true,
				column_data_type: 'text',
				html_data_type: 'text',
				exclude_label: 'exclude',
				style_class: '',
                datepicker_type: 'jquery-ui',
				range_data_type: 'single',
				range_data_type_delim: '-'
			},
			adaptContainerCssClassImpl = function (dummy) { return ''; };

		$.extend(true, default_options, params);

		if (options_arg.length === undefined) {
			options[selector_arg] = options_arg;
			return;
		}
		for (i = 0; i < options_arg.length; i++) {
			if (options_arg[i].select_type === 'select2') {
				default_options.select_type_options = {
					adaptContainerCssClass: adaptContainerCssClassImpl
				};
			}
			//no individual reset button for externally_triggered mode
			if (default_options.externally_triggered === true) {
				options_arg[i].filter_reset_button_text = false;
			}
			//validate custom function required attributes
			if (options_arg[i].filter_type !== undefined && options_arg[i].filter_type.indexOf('custom_func') !== -1) {
				if (options_arg[i].custom_func === undefined) {
					alert('You are trying to use filter_type: "custom_func / multi_select_custom_func" for column ' + options_arg[i].column_number + ' but there is no such custom_func attribute provided (custom_func: \"function reference goes here...\")');
					return;
				}
			}
			col_num_as_int = +options_arg[i].column_number;
			if (isNaN(col_num_as_int)) {
				tmpOptions[options_arg[i].column_number_str] = $.extend(true, {}, default_options, options_arg[i]);
			} else {
				tmpOptions[col_num_as_int] = $.extend(true, {}, default_options, options_arg[i]);
			}
		}
		options[selector_arg] = tmpOptions;
	}

	//taken and modified from DataTables 1.10.0-beta.2 source
	function yadcfVersionCheck(version) {
		var aThis = $.fn.dataTable.ext.sVersion.split('.'),
			aThat = version.split('.'),
			iThis,
			iThat,
			i,
			iLen;

		for (i = 0, iLen = aThat.length; i < iLen; i++) {
			iThis = parseInt(aThis[i], 10) || 0;
			iThat = parseInt(aThat[i], 10) || 0;

			// Parts are the same, keep comparing
			if (iThis === iThat) {
				continue;
			}

			// Parts are different, return immediately
			return iThis > iThat;
		}

		return true;
	}

	function calculateColumnNumber(column_number, pTable) {
		var col_num_visible_iter,
			col_num_visible = column_number;
		for (col_num_visible_iter = 0; col_num_visible_iter < pTable.fnSettings().aoColumns.length && col_num_visible_iter < column_number; col_num_visible_iter++) {
			if (pTable.fnSettings().aoColumns[col_num_visible_iter].bVisible === false) {
				col_num_visible++;
			}
		}
		return col_num_visible;
	}

	function resetIApiIndex() {
		$.fn.dataTableExt.iApiIndex = 0;

	}

	function generateTableSelectorJQFriendly(tmpStr) {
		return tmpStr.replace(":", "-").replace("(", "").replace(")", "").replace(".", "-").replace("#", "-");
	}

	function escapeRegExp(string) {
		return string.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1");
	}

	function replaceAll(string, find, replace) {
		return string.replace(new RegExp(escapeRegExp(find), 'g'), replace);
	}

	function generateTableSelectorJQFriendlyNew(tmpStr) {
		tmpStr = replaceAll(tmpStr, ":", "-");
		tmpStr = replaceAll(tmpStr, "(", "");
		tmpStr = replaceAll(tmpStr, ")", "");
		tmpStr = replaceAll(tmpStr, ",", "");
		tmpStr = replaceAll(tmpStr, ".", "-");
		tmpStr = replaceAll(tmpStr, "#", "-");
		return tmpStr;
	}

	yadcfDelay = (function () {
		var timer = 0;
		return function (callback, ms, param) {
			clearTimeout(timer);
			timer = setTimeout(function () {
				callback(param);
			}, ms);
			return timer;
		};
	}());

	function initializeSelectPlugin(selectType, $selectObject, select_type_options) {
		if (selectType === 'chosen') {
			$selectObject.chosen(select_type_options);
			$selectObject.next().attr("onclick", "yadcf.stopPropagation(event);").attr("onmousedown", "yadcf.stopPropagation(event);");
		} else if (selectType === 'select2') {
			$selectObject.select2(select_type_options);
			if ($selectObject.next().hasClass('select2-container')) {
				$selectObject.next().attr("onclick", "yadcf.stopPropagation(event);").attr("onmousedown", "yadcf.stopPropagation(event);");
			}
		} else if (selectType === 'custom_select') {
			selectElementCustomInitFunc($selectObject);
			$selectObject.next().attr("onclick", "yadcf.stopPropagation(event);").attr("onmousedown", "yadcf.stopPropagation(event);");
		}
	}

	function refreshSelectPlugin(selectType, $selectObject, val) {
		if (selectType === 'chosen') {
			$selectObject.trigger("chosen:updated");
		} else if (selectType === 'select2') {
			$selectObject.val(val);
		} else if (selectType === 'custom_select') {
			selectElementCustomRefreshFunc($selectObject);
		}
	}

	function initSelectPluginCustomTriggers(initFunc, refreshFunc) {
		selectElementCustomInitFunc = initFunc;
		selectElementCustomRefreshFunc = refreshFunc;
	}

	//Used by exFilterColumn for translating readable search value into proper search string for datatables filtering
	function yadcfMatchFilterString(table_arg, column_number, selected_value, filter_match_mode, multiple) {
		var case_insensitive = yadcf.getOptions(table_arg.selector)[column_number].case_insensitive,
			ret_val;

		table_arg.fnSettings().aoPreSearchCols[column_number].bSmart = false;
		table_arg.fnSettings().aoPreSearchCols[column_number].bRegex = true;
		table_arg.fnSettings().aoPreSearchCols[column_number].bCaseInsensitive = case_insensitive;

		if (multiple === undefined || multiple === false) {
			if (filter_match_mode === "contains") {
				table_arg.fnSettings().aoPreSearchCols[column_number].bSmart = true;
				table_arg.fnSettings().aoPreSearchCols[column_number].bRegex = false;
				ret_val = selected_value;
			} else if (filter_match_mode === "exact") {
				ret_val = "^" + selected_value + "$";
			} else if (filter_match_mode === "startsWith") {
				ret_val = "^" + selected_value;
			} else if (filter_match_mode === "regex") {
				ret_val = selected_value;
			}
		} else {
			if (filter_match_mode === "contains") {
				ret_val = selected_value.join("|");
			} else if (filter_match_mode === "exact") {
				ret_val = "^(" + selected_value.join("|") + ")$";
			} else if (filter_match_mode === "startsWith") {
				ret_val = "^(" + selected_value.join("|") + ")";
			} else if (filter_match_mode === "regex") {
				ret_val = selected_value;
			}
		}
		return ret_val;
	}

	function yadcfMatchFilter(oTable, selected_value, filter_match_mode, column_number, exclude) {
		var case_insensitive = yadcf.getOptions(oTable.selector)[column_number].case_insensitive;
		if (exclude !== true) {
			if (filter_match_mode === "contains") {
				oTable.fnFilter(selected_value, column_number, false, true, true, case_insensitive);
			} else if (filter_match_mode === "exact") {
				selected_value = escapeRegExp(selected_value);
				oTable.fnFilter("^" + selected_value + "$", column_number, true, false, true, case_insensitive);
			} else if (filter_match_mode === "startsWith") {
				selected_value = escapeRegExp(selected_value);
				oTable.fnFilter("^" + selected_value, column_number, true, false, true, case_insensitive);
			} else if (filter_match_mode === "regex") {
				try {
					//validate regex, only call fnFilter if valid
					new RegExp(selected_value);
				} catch (error) {
					return;
				}
				oTable.fnFilter(selected_value, column_number, true, false, true, case_insensitive);
			}
		} else {
			oTable.fnFilter("^((?!" + selected_value + ").)*$", column_number, true, false, true, case_insensitive);
		}
	}
	function yadcfParseMatchFilter(tmpStr, filter_match_mode) {
		var retVal;
		if (filter_match_mode === "contains") {
			retVal = tmpStr;
		} else if (filter_match_mode === "exact") {
			retVal = tmpStr.substring(1, tmpStr.length - 1);
			retVal = retVal.replace(/([\\])/g, '');
		} else if (filter_match_mode === "startsWith") {
			retVal = tmpStr.substring(1, tmpStr.length);
			retVal = retVal.replace(/([\\])/g, '');
		} else if (filter_match_mode === "regex") {
			retVal = tmpStr;
		}
		return retVal;
	}

	function doFilterCustomDateFunc(arg, table_selector_jq_friendly, column_number) {
		var oTable = oTables[table_selector_jq_friendly],
			yadcfState,
			columnObj = getOptions(oTable.selector)[column_number];

		if (arg === "clear") {
			if (exGetColumnFilterVal(oTable, column_number) === '') {
				return;
			}
			$("#yadcf-filter-" + table_selector_jq_friendly + "-" + column_number).val('-1').focus();
			$("#yadcf-filter-" + table_selector_jq_friendly + "-" + column_number).removeClass("inuse");

			refreshSelectPlugin(columnObj.select_type, $("#yadcf-filter-" + table_selector_jq_friendly + "-" + column_number), '-1');

		} else {
			$("#yadcf-filter-" + table_selector_jq_friendly + "-" + column_number).addClass("inuse");
		}

		if (!oTable.fnSettings().oLoadedState) {
			oTable.fnSettings().oLoadedState = {};
			oTable.fnSettings().oApi._fnSaveState(oTable.fnSettings());
		}
		if (oTable.fnSettings().oFeatures.bStateSave === true) {
			if (oTable.fnSettings().oLoadedState.yadcfState !== undefined && oTable.fnSettings().oLoadedState.yadcfState[table_selector_jq_friendly] !== undefined) {
				oTable.fnSettings().oLoadedState.yadcfState[table_selector_jq_friendly][column_number] =
					{
						'from' : arg.value
					};
			} else {
				yadcfState = {};
				yadcfState[table_selector_jq_friendly] = [];
				yadcfState[table_selector_jq_friendly][column_number] = {
					'from' : arg.value
				};
				oTable.fnSettings().oLoadedState.yadcfState = yadcfState;
			}
			oTable.fnSettings().oApi._fnSaveState(oTable.fnSettings());
		}

		oTable.fnDraw();
	}

	function calcColumnNumberFilter(settingsDt, column_number, table_selector_jq_friendly) {
		var column_number_filter;
		if ((settingsDt.oSavedState != undefined && settingsDt.oSavedState.ColReorder !== undefined)
				|| settingsDt._colReorder != undefined
				|| (plugins[table_selector_jq_friendly] !== undefined && plugins[table_selector_jq_friendly].ColReorder !== undefined)) {
			initColReorder2(settingsDt, table_selector_jq_friendly);
			column_number_filter = plugins[table_selector_jq_friendly].ColReorder[column_number];
		} else {
			column_number_filter = column_number;
		}
		return column_number_filter;
	}

	function doFilter(arg, table_selector_jq_friendly, column_number, filter_match_mode) {
		$.fn.dataTableExt.iApiIndex = oTablesIndex[table_selector_jq_friendly];

		var oTable = oTables[table_selector_jq_friendly],
			selected_value,
			column_number_filter,
			columnObj,
			settingsDt = getSettingsObjFromTable(oTable);

		column_number_filter = calcColumnNumberFilter(settingsDt, column_number, table_selector_jq_friendly);

		columnObj = getOptions(oTable.selector)[column_number];
		if (arg === "clear") {
			if (exGetColumnFilterVal(oTable, column_number) === '') {
				return;
			}
			$("#yadcf-filter-" + table_selector_jq_friendly + "-" + column_number).val("-1").focus();
			$("#yadcf-filter-" + table_selector_jq_friendly + "-" + column_number).removeClass("inuse");
			$(document).data("#yadcf-filter-" + table_selector_jq_friendly + "-" + column_number + "_val", "-1");
			oTable.fnFilter("", column_number_filter);
			resetIApiIndex();

			refreshSelectPlugin(columnObj.select_type, $("#yadcf-filter-" + table_selector_jq_friendly + "-" + column_number), '-1');
			return;
		}

		$("#yadcf-filter-" + table_selector_jq_friendly + "-" + column_number).addClass("inuse");

		$(document).data("#yadcf-filter-" + table_selector_jq_friendly + "-" + column_number + "_val", arg.value);

		selected_value = $.trim($(arg).find('option:selected').val());

		if (arg.value !== "-1") {
			yadcfMatchFilter(oTable, selected_value, filter_match_mode, column_number_filter);
		} else {
			oTable.fnFilter("", column_number_filter);
			$("#yadcf-filter-" + table_selector_jq_friendly + "-" + column_number).removeClass("inuse");
		}
		resetIApiIndex();
	}

	function doFilterMultiSelect(arg, table_selector_jq_friendly, column_number, filter_match_mode) {
		$.fn.dataTableExt.iApiIndex = oTablesIndex[table_selector_jq_friendly];
		var oTable = oTables[table_selector_jq_friendly],
			selected_values = $(arg).val(),
			selected_values_trimmed = [],
			i,
			stringForSearch,
			column_number_filter,
			settingsDt = getSettingsObjFromTable(oTable);

		column_number_filter = calcColumnNumberFilter(settingsDt, column_number, table_selector_jq_friendly);
		$(document).data("#yadcf-filter-" + table_selector_jq_friendly + "-" + column_number + "_val", selected_values);

		if (selected_values !== null) {
			for (i = selected_values.length - 1; i >= 0; i--) {
				if (selected_values[i] === "-1") {
					selected_values.splice(i, 1);
					break;
				}
			}
			for (i = 0; i < selected_values.length; i++) {
				selected_values_trimmed.push($.trim(selected_values[i]));
			}
			if (selected_values_trimmed.length !== 0) {
				stringForSearch = selected_values_trimmed.join('narutouzomaki');
				stringForSearch = stringForSearch.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1");
				stringForSearch = stringForSearch.split('narutouzomaki').join('|');
				if (filter_match_mode === "contains") {
					oTable.fnFilter(stringForSearch, column_number_filter, true, false, true);
				} else if (filter_match_mode === "exact") {
					oTable.fnFilter("^(" + stringForSearch + ")$", column_number_filter, true, false, true);
				} else if (filter_match_mode === "startsWith") {
					oTable.fnFilter("^(" + stringForSearch + ")", column_number_filter, true, false, true);
				} else if (filter_match_mode === "regex") {
					oTable.fnFilter(stringForSearch, column_number_filter, true, false, true);
				}
			} else {
				oTable.fnFilter("", column_number_filter);
			}
		} else {
			oTable.fnFilter("", column_number_filter);
		}
		resetIApiIndex();
	}

	function yadcfParseMatchFilterMultiSelect(tmpStr, filter_match_mode) {
		var retVal;
		if (filter_match_mode === "contains") {
			retVal = tmpStr;
		} else if (filter_match_mode === "exact") {
			retVal = tmpStr.substring(1, tmpStr.length - 1);
			retVal = retVal.substring(1, retVal.length - 1);
		} else if (filter_match_mode === "startsWith") {
			retVal = tmpStr.substring(1, tmpStr.length);
			retVal = retVal.substring(1, retVal.length - 1);
		} else if (filter_match_mode === "regex") {
			retVal = tmpStr;
		}
		return retVal;
	}

	function doFilterAutocomplete(arg, table_selector_jq_friendly, column_number, filter_match_mode) {
		$.fn.dataTableExt.iApiIndex = oTablesIndex[table_selector_jq_friendly];
		var oTable = oTables[table_selector_jq_friendly],
			column_number_filter,
			settingsDt = getSettingsObjFromTable(oTable);

		column_number_filter = calcColumnNumberFilter(settingsDt, column_number, table_selector_jq_friendly);

		if (arg === "clear") {
			if (exGetColumnFilterVal(oTable, column_number) === '') {
				return;
			}
			$("#yadcf-filter-" + table_selector_jq_friendly + "-" + column_number).val("").focus();
			$("#yadcf-filter-" + table_selector_jq_friendly + "-" + column_number).removeClass("inuse");
			$(document).removeData("#yadcf-filter-" + table_selector_jq_friendly + "-" + column_number + "_val");
			oTable.fnFilter("", column_number_filter);
			resetIApiIndex();
			return;
		}

		$("#yadcf-filter-" + table_selector_jq_friendly + "-" + column_number).addClass("inuse");

		$(document).data("#yadcf-filter-" + table_selector_jq_friendly + "-" + column_number + "_val", arg.value);

		yadcfMatchFilter(oTable, arg.value, filter_match_mode, column_number_filter);

		resetIApiIndex();
	}

	function autocompleteSelect(event, ui) {
		event = eventTargetFixUp(event);
		var table_column = event.target.id.replace("yadcf-filter-", ""),
			dashIndex = table_column.lastIndexOf("-"),
			table_selector_jq_friendly = table_column.substring(0, dashIndex),
			col_num = parseInt(table_column.substring(dashIndex + 1), 10),
			filter_match_mode = $(event.target).attr("filter_match_mode");
		doFilterAutocomplete(ui.item, table_selector_jq_friendly, col_num, filter_match_mode);
	}

	function sortNumAsc(a, b) {
		return a - b;
	}

	function sortNumDesc(a, b) {
		return b - a;
	}

	function findMinInArray(array, columnObj) {
		var narray = [], i, num;
		for (i = 0; i < array.length; i++) {
			if (array[i] !== null) {
				if (columnObj.ignore_char !== undefined) {
					array[i] = array[i].toString().replace(columnObj.ignore_char, "");
				}
				if (columnObj.range_data_type === 'single') {
					num = +array[i];
				} else {
					num = array[i].split(columnObj.range_data_type_delim);
					num = num[0];
				}
				if (!isNaN(num)) {
					narray.push(num);
				}
			}
		}
		return Math.min.apply(Math, narray);
	}

	function findMaxInArray(array, columnObj) {
		var narray = [], i, num;
		for (i = 0; i < array.length; i++) {
			if (array[i] !== null) {
				if (columnObj.ignore_char !== undefined) {
					array[i] = array[i].toString().replace(columnObj.ignore_char, "");
				}
				if (columnObj.range_data_type === 'single') {
					num = +array[i];
				} else {
					num = array[i].split(columnObj.range_data_type_delim);
					num = num[1];
				}
				if (!isNaN(num)) {
					narray.push(num);
				}
			}
		}
		return Math.max.apply(Math, narray);
	}

	function addRangeNumberAndSliderFilterCapability(table_selector_jq_friendly, fromId, toId, col_num, ignore_char) {
 
		$.fn.dataTableExt.afnFiltering.push(
			function (settingsDt, aData, iDataIndex, rowData) {
				var min,
					max,
					val,
					retVal = false,
					table_selector_jq_friendly_local = table_selector_jq_friendly,
					current_table_selector_jq_friendly = yadcf.generateTableSelectorJQFriendly(settingsDt.oInstance.selector),
					ignore_char_local = ignore_char,
					column_data_type,
					html_data_type,
					i,
					columnObjKey,
					columnObj,
					column_number_filter,
					valFrom,
					valTo;

				if (table_selector_jq_friendly_local !== current_table_selector_jq_friendly) {
					return true;
				}
				columnObj = getOptions(settingsDt.oInstance.selector)[col_num];
				if (columnObj.filter_type === 'range_number_slider') {
					min = $('#' + fromId).text();
					max = $('#' + toId).text();
				} else {
					min = document.getElementById(fromId).value;
					max = document.getElementById(toId).value;
				}

				column_number_filter = calcColumnNumberFilter(settingsDt, col_num, table_selector_jq_friendly);

				if (rowData !== undefined) {
					aData = rowData;
					if (columnObj.column_number_data !== undefined) {
						column_number_filter = columnObj.column_number_data;
						val = dot2obj(aData, column_number_filter);
					} else {
						val = aData[column_number_filter];
					}
				} else {
					val = aData[column_number_filter];
				}
				if (!isFinite(min) || !isFinite(max)) {
					return true;
				}
				column_data_type = columnObj.column_data_type;
				html_data_type = columnObj.html_data_type;

				if (column_data_type === "html" || column_data_type === "rendered_html") {
					if (html_data_type === undefined) {
						html_data_type = "text";
					}
					if ($(val).length !== 0) {
						switch (html_data_type) {
						case "text":
							val = $(val).text();
							break;
						case "value":
							val = $(val).val();
							break;
						case "id":
							val = val.id;
							break;
						case "selector":
							val = $(val).find(columnObj.html_data_selector).text();
							break;
						}
					}
				} else {
					if (typeof val === 'object') {
						if (columnObj.html5_data !== undefined) {
							val = val['@' + columnObj.html5_data];
						}
					}
				}
				if (ignore_char_local !== undefined) {
					min = min.replace(ignore_char_local, "");
					max = max.replace(ignore_char_local, "");
					if (val) {
						val = val.toString().replace(ignore_char_local, "");
					} else {
						val = "";
					}
				}
				min = (min !== "") ? (+min) : min;
				max = (max !== "") ? (+max) : max;
				if (columnObj.range_data_type === 'single') {
					val = (val !== "") ? (+val) : val;
					if (min === "" && max === "") {
						retVal = true;
					} else if (min === "" && val <= max) {
						retVal = true;
					} else if (min <= val && "" === max) {
						retVal = true;
					} else if (min <= val && val <= max) {
						retVal = true;
					} else if (val === '' || isNaN(val)) {
						retVal = true;
					}
				} else if (columnObj.range_data_type === 'range') {
					val = val.split(columnObj.range_data_type_delim);
					valFrom = (val[0] !== "") ? (+val[0]) : val[0];
					valTo = (val[1] !== "") ? (+val[1]) : val[1];
					if (min === "" && max === "") {
						retVal = true;
					} else if (min === "" && valTo <= max) {
						retVal = true;
					} else if (min <= valFrom && "" === max) {
						retVal = true;
					} else if (min <= valFrom && valTo <= max) {
						retVal = true;
					} else if ((valFrom === '' || isNaN(valFrom)) && (valTo === '' || isNaN(valTo))) {
						retVal = true;
					}
				}
				return retVal;
			}
		);
	}

	function addCustomFunctionFilterCapability(table_selector_jq_friendly, filterId, col_num) {

		$.fn.dataTableExt.afnFiltering.push(
			function (settingsDt, aData, iDataIndex, stateVal) {
				var filterVal = $('#' + filterId).val(),
					columnVal,
					retVal = false,
					table_selector_jq_friendly_local = table_selector_jq_friendly,
					current_table_selector_jq_friendly = yadcf.generateTableSelectorJQFriendly(settingsDt.oInstance.selector),
					custom_func,
					column_number_filter;

				if (table_selector_jq_friendly_local !== current_table_selector_jq_friendly || filterVal === '-1') {
					return true;
				}

				column_number_filter = calcColumnNumberFilter(settingsDt, col_num, table_selector_jq_friendly);

				columnVal = aData[column_number_filter] === "-" ? 0 : aData[column_number_filter];

				custom_func = getOptions(settingsDt.oInstance.selector)[col_num].custom_func;

				retVal = custom_func(filterVal, columnVal, aData);

				return retVal;
			}
		);
	}
	function addRangeDateFilterCapability(table_selector_jq_friendly, fromId, toId, col_num, date_format) {

		$.fn.dataTableExt.afnFiltering.push(
			function (settingsDt, aData, iDataIndex, rowData) {
				var min = document.getElementById(fromId) !== null ? document.getElementById(fromId).value : "",
					max = document.getElementById(toId) !== null ? document.getElementById(toId).value : "",
					val,
					retVal = false,
					table_selector_jq_friendly_local = table_selector_jq_friendly,
					current_table_selector_jq_friendly = yadcf.generateTableSelectorJQFriendly(settingsDt.oInstance.selector),
					column_data_type,
					html_data_type,
					i,
					columnObjKey,
					columnObj,
					column_number_filter;

				if (table_selector_jq_friendly_local !== current_table_selector_jq_friendly) {
					return true;
				}
				columnObj = getOptions(settingsDt.oInstance.selector)[col_num];

				column_number_filter = calcColumnNumberFilter(settingsDt, col_num, table_selector_jq_friendly);

				if (rowData !== undefined) {
					aData = rowData;
					if (columnObj.column_number_data !== undefined) {
						column_number_filter = columnObj.column_number_data;
						val = dot2obj(aData, column_number_filter);
					} else {
						val = aData[column_number_filter];
					}
				} else {
					val = aData[column_number_filter];
				}

				column_data_type = columnObj.column_data_type;
				html_data_type = columnObj.html_data_type;

				if (column_data_type === "html" || column_data_type === "rendered_html") {
					if (html_data_type === undefined) {
						html_data_type = "text";
					}
					if ($(val).length !== 0) {
						switch (html_data_type) {
						case "text":
							val = $(val).text();
							break;
						case "value":
							val = $(val).val();
							break;
						case "id":
							val = val.id;
							break;
						case "selector":
							val = $(val).find(columnObj.html_data_selector).text();
							break;
						}
					}
				} else {
					if (typeof val === 'object') {
						if (columnObj.html5_data !== undefined) {
							val = val['@' + columnObj.html5_data];
						}
					}
				}

				try {
					if (min.length === (date_format.length + 2) || columnObj.datepicker_type === 'bootstrap-datetimepicker') {
                        if (columnObj.datepicker_type === 'jquery-ui') {
						    min = (min !== "") ? $.datepicker.parseDate(date_format, min) : min;
                        } else if (columnObj.datepicker_type === 'bootstrap-datetimepicker') {
                            min = (min !== "") ? moment(min, date_format).toDate() : min;
                        }
					}
				} catch (err1) {}
				try {
					if (max.length === (date_format.length + 2) || columnObj.datepicker_type === 'bootstrap-datetimepicker') {
                        if (columnObj.datepicker_type === 'jquery-ui') {
                            max = (max !== "") ? $.datepicker.parseDate(date_format, max) : max;
                        } else if (columnObj.datepicker_type === 'bootstrap-datetimepicker') {
                            max = (max !== "") ? moment(max, date_format).toDate() : max;
                        }
					}
				} catch (err2) {}
				try {
                    if (columnObj.datepicker_type === 'jquery-ui') {
                        val = (val !== "") ? $.datepicker.parseDate(date_format, val) : val;
                    } else if (columnObj.datepicker_type === 'bootstrap-datetimepicker') {
                        val = (val !== "") ? moment(val, date_format).toDate() : val;
                    }
				} catch (err3) {}

				if ((min === "" || !(min instanceof Date)) && (max === "" || !(max instanceof Date))) {
					retVal = true;
				} else if (min === "" && val <= max) {
					retVal = true;
				} else if (min <= val && "" === max) {
					retVal = true;
				} else if (min <= val && val <= max) {
					retVal = true;
				}

				return retVal;
			}
		);
	}

	function addRangeNumberFilter(filter_selector_string, table_selector_jq_friendly, column_number, filter_reset_button_text, filter_default_label, ignore_char) {
		var fromId = "yadcf-filter-" + table_selector_jq_friendly + "-from-" + column_number,
			toId = "yadcf-filter-" + table_selector_jq_friendly + "-to-" + column_number,
			filter_selector_string_tmp,
			filter_wrapper_id,
			oTable,
			columnObj,
			filterActionStr;

		filter_wrapper_id = "yadcf-filter-wrapper-" + table_selector_jq_friendly + "-" + column_number;

		if ($("#" + filter_wrapper_id).length > 0) {
			return;
		}
		$.fn.dataTableExt.iApiIndex = oTablesIndex[table_selector_jq_friendly];
		oTable = oTables[table_selector_jq_friendly];
		columnObj = getOptions(oTable.selector)[column_number];

		//add a wrapper to hold both filter and reset button
		$(filter_selector_string).append("<div onmousedown=\"yadcf.stopPropagation(event);\" onclick=\"yadcf.stopPropagation(event);\"  id=\"" + filter_wrapper_id + "\" class=\"yadcf-filter-wrapper\"></div>");
		filter_selector_string = filter_selector_string + " div.yadcf-filter-wrapper";
		filter_selector_string_tmp = filter_selector_string;

		$(filter_selector_string).append("<div id=\"yadcf-filter-wrapper-inner-" + table_selector_jq_friendly + "-" + column_number + "\" class=\"yadcf-filter-wrapper-inner\"></div>");
		filter_selector_string = filter_selector_string + " div.yadcf-filter-wrapper-inner";

		filterActionStr = 'onkeyup="yadcf.rangeNumberKeyUP(\'' + table_selector_jq_friendly + '\',event);"';
		if (columnObj.externally_triggered === true) {
			filterActionStr = '';
		}

		$(filter_selector_string).append("<input placeholder=\"" + filter_default_label[0] + "\" id=\"" + fromId + "\" class=\"yadcf-filter-range-number yadcf-filter-range\" " + filterActionStr + "></input>");
		$(filter_selector_string).append("<span class=\"yadcf-filter-range-number-seperator\" >" +
			"</span>");
		$(filter_selector_string).append("<input placeholder=\"" + filter_default_label[1] + "\" id=\"" + toId + "\" class=\"yadcf-filter-range-number yadcf-filter-range\" " + filterActionStr + "></input>");

		if (filter_reset_button_text !== false) {
			$(filter_selector_string_tmp).append("<button type=\"button\" onmousedown=\"yadcf.stopPropagation(event);\" " +
				"onclick=\"yadcf.stopPropagation(event);yadcf.rangeClear('" + table_selector_jq_friendly + "',event); return false;\" class=\"yadcf-filter-reset-button\">" + filter_reset_button_text + "</button>");
		}

		if (oTable.fnSettings().oFeatures.bStateSave === true && oTable.fnSettings().oLoadedState) {
			if (oTable.fnSettings().oLoadedState.yadcfState && oTable.fnSettings().oLoadedState.yadcfState[table_selector_jq_friendly] && oTable.fnSettings().oLoadedState.yadcfState[table_selector_jq_friendly][column_number]) {
				$('#' + fromId).val(oTable.fnSettings().oLoadedState.yadcfState[table_selector_jq_friendly][column_number].from);
				if (oTable.fnSettings().oLoadedState.yadcfState[table_selector_jq_friendly][column_number].from !== "") {
					$('#' + fromId).addClass("inuse");
				}
				$('#' + toId).val(oTable.fnSettings().oLoadedState.yadcfState[table_selector_jq_friendly][column_number].to);
				if (oTable.fnSettings().oLoadedState.yadcfState[table_selector_jq_friendly][column_number].to !== "") {
					$('#' + toId).addClass("inuse");
				}
			}
		}
		resetIApiIndex();

		if (oTable.fnSettings().oFeatures.bServerSide !== true) {
			addRangeNumberAndSliderFilterCapability(table_selector_jq_friendly, fromId, toId, column_number, ignore_char);
		}

	}

	function dateSelectSingle(pDate, pEvent, clear) {
		var oTable,
			date,
			event,
			column_number,
			dashIndex,
			table_selector_jq_friendly,
			date_str,
			column_number_filter,
			settingsDt,
			columnObj;

		if (pDate.type === 'dp') {
			event = pDate.target;
		} else {
			date = pDate;
			event = pEvent;
		}
		column_number = $(event).attr('id').replace('yadcf-filter-', '').replace('-date', '').replace('-reset', '');
		dashIndex = column_number.lastIndexOf("-");
		table_selector_jq_friendly = column_number.substring(0, dashIndex);

		column_number = column_number.substring(dashIndex + 1);
		$.fn.dataTableExt.iApiIndex = oTablesIndex[table_selector_jq_friendly];
		oTable = oTables[table_selector_jq_friendly];
		settingsDt = getSettingsObjFromTable(oTable);
		columnObj = getOptions(oTable.selector)[column_number];

		if (pDate.type === 'dp') {
			if (pDate.date !== false) {
				date = pDate.date.format(columnObj.date_format);
			} else {
				clear = 'clear';
			}
			$(event).blur();
		}

		column_number_filter = calcColumnNumberFilter(settingsDt, column_number, table_selector_jq_friendly);

		if (clear === undefined) {
			date_str = document.getElementById($(event).attr('id')).value;
			oTable.fnFilter(date, column_number_filter);
			$('#yadcf-filter-' + table_selector_jq_friendly + '-' + column_number).addClass("inuse");
		} else if (clear === 'clear') {
			if (exGetColumnFilterVal(oTable, column_number) === '') {
				return;
			}
			oTable.fnFilter('', column_number_filter);
			$('#yadcf-filter-' + table_selector_jq_friendly + '-' + column_number).val('').removeClass("inuse");
		}

		resetIApiIndex();
	}

	function dateSelect(pDate, pEvent) {
		var oTable,
			column_number,
			dashIndex,
			table_selector_jq_friendly,
			yadcfState,
			from,
			to,
			date_format,
			date,
			event;

		if (pDate.type === 'dp') {
			event = pDate.target;
		} else {
			date = pDate;
			event = pEvent;
		}

		column_number = $(event).attr("id").replace("yadcf-filter-", "").replace("-from-date", "").replace("-to-date", "");
		dashIndex = column_number.lastIndexOf("-");
		table_selector_jq_friendly = column_number.substring(0, dashIndex);

        column_number = column_number.substring(dashIndex + 1);

        $.fn.dataTableExt.iApiIndex = oTablesIndex[table_selector_jq_friendly];

		oTable = oTables[table_selector_jq_friendly];

		if (pDate.type === 'dp') {
			event = pDate.target;
			if (pDate.date === false) {
				$(event).removeClass("inuse");
				$(event).data("DateTimePicker").minDate(false);
			} else {
				$(event).addClass("inuse");
			}
			$(event).blur();
		} else {
			$(event).addClass("inuse");
		}

		if ($(event).attr("id").indexOf("-from-") !== -1) {
			from = document.getElementById($(event).attr("id")).value;
			to = document.getElementById($(event).attr("id").replace("-from-", "-to-")).value;
		} else {
			to = document.getElementById($(event).attr("id")).value;
			from = document.getElementById($(event).attr("id").replace("-to-", "-from-")).value;
		}

		if (oTable.fnSettings().oFeatures.bServerSide !== true) {
			oTable.fnDraw();
		} else {
			oTable.fnFilter(from + '-yadcf_delim-' + to, column_number);
		}

		if (!oTable.fnSettings().oLoadedState) {
			oTable.fnSettings().oLoadedState = {};
			oTable.fnSettings().oApi._fnSaveState(oTable.fnSettings());
		}
		if (oTable.fnSettings().oFeatures.bStateSave === true) {
			if (oTable.fnSettings().oLoadedState.yadcfState !== undefined && oTable.fnSettings().oLoadedState.yadcfState[table_selector_jq_friendly] !== undefined) {
				oTable.fnSettings().oLoadedState.yadcfState[table_selector_jq_friendly][column_number] =
					{
						'from' : from,
						'to' : to
					};
			} else {
				yadcfState = {};
				yadcfState[table_selector_jq_friendly] = [];
				yadcfState[table_selector_jq_friendly][column_number] = {
					'from' : from,
					'to' : to
				};
				oTable.fnSettings().oLoadedState.yadcfState = yadcfState;
			}
			oTable.fnSettings().oApi._fnSaveState(oTable.fnSettings());
		}

		resetIApiIndex();
	}

	function addRangeDateFilter(filter_selector_string, table_selector_jq_friendly, column_number, filter_reset_button_text, filter_default_label, date_format) {
		var fromId = "yadcf-filter-" + table_selector_jq_friendly + "-from-date-" + column_number,
			toId = "yadcf-filter-" + table_selector_jq_friendly + "-to-date-" + column_number,
			filter_selector_string_tmp,
			filter_wrapper_id,
			oTable,
			columnObj,
			datepickerObj = {},
			filterActionStr,
			filterClass = '',
			$fromInput,
            $toInput,
			innerWrapperAdditionalClass = '';

		filter_wrapper_id = "yadcf-filter-wrapper-" + table_selector_jq_friendly + "-" + column_number;

		if ($("#" + filter_wrapper_id).length > 0) {
			return;
		}
		$.fn.dataTableExt.iApiIndex = oTablesIndex[table_selector_jq_friendly];
		oTable = oTables[table_selector_jq_friendly];
		columnObj = getOptions(oTable.selector)[column_number];
		if (columnObj.datepicker_type === 'bootstrap-datepicker') {
			innerWrapperAdditionalClass = 'input-daterange';
		}
		//add a wrapper to hold both filter and reset button
		$(filter_selector_string).append("<div onmousedown=\"yadcf.stopPropagation(event);\" onclick=\"yadcf.stopPropagation(event);\"  id=\"" + filter_wrapper_id + "\" class=\"yadcf-filter-wrapper\"></div>");
		filter_selector_string = filter_selector_string + " div.yadcf-filter-wrapper";
		filter_selector_string_tmp = filter_selector_string;

		$(filter_selector_string).append("<div id=\"yadcf-filter-wrapper-inner-" + table_selector_jq_friendly + "-" + column_number + "\" class=\"yadcf-filter-wrapper-inner " + innerWrapperAdditionalClass + "\"></div>");
		filter_selector_string = filter_selector_string + " div.yadcf-filter-wrapper-inner";

		filterActionStr = 'onkeyup="yadcf.rangeDateKeyUP(\'' + table_selector_jq_friendly + '\',\'' + date_format + '\',event);"';
		if (columnObj.externally_triggered === true) {
			filterActionStr = '';
		}

		$(filter_selector_string).append("<input placeholder=\"" + filter_default_label[0] + "\" id=\"" + fromId + "\" class=\"yadcf-filter-range-date yadcf-filter-range\" " + filterActionStr + "></input>");
		$(filter_selector_string).append("<span class=\"yadcf-filter-range-date-seperator\" >" +
			"</span>");
		$(filter_selector_string).append("<input placeholder=\"" + filter_default_label[1] + "\" id=\"" + toId + "\" class=\"yadcf-filter-range-date yadcf-filter-range\" " + filterActionStr + "></input>");

		$fromInput = $("#" + fromId);
		$toInput = $("#" + toId);

		if (filter_reset_button_text !== false) {
			$(filter_selector_string_tmp).append("<button type=\"button\" onmousedown=\"yadcf.stopPropagation(event);\" " +
				"onclick=\"yadcf.stopPropagation(event);yadcf.rangeClear('" + table_selector_jq_friendly + "',event); return false;\" class=\"yadcf-filter-reset-button\">" + filter_reset_button_text + "</button>");
		}

        if (columnObj.datepicker_type === 'jquery-ui') {
		    datepickerObj.dateFormat = date_format;
        } else if (columnObj.datepicker_type === 'bootstrap-datetimepicker') {
		    datepickerObj.format = date_format;
        }

		if (columnObj.externally_triggered !== true) {
            if (columnObj.datepicker_type === 'jquery-ui') {
			    datepickerObj.onSelect = dateSelect;
            }
			// for 'bootstrap-datetimepicker' its implemented below...
        }

        datepickerObj = $.extend({}, columnObj.filter_plugin_options, datepickerObj);

        if (columnObj.datepicker_type === 'jquery-ui') {
            $fromInput.datepicker($.extend(datepickerObj, {onClose: function (selectedDate) {
                $toInput.datepicker('option', 'minDate', selectedDate);
            }  }));
            $toInput.datepicker($.extend(datepickerObj, {onClose: function (selectedDate) {
                $fromInput.datepicker('option', 'maxDate', selectedDate);
            }  }));

        } else if (columnObj.datepicker_type === 'bootstrap-datetimepicker') {
			datepickerObj.useCurrent = false;
            $fromInput.datetimepicker(datepickerObj);
            $toInput.datetimepicker(datepickerObj);
            $fromInput.on("dp.change", function (e) {
                $toInput.data("DateTimePicker").minDate(e.date);
            });
            $toInput.on("dp.change", function (e) {
                $fromInput.data("DateTimePicker").maxDate(e.date);
            });
		    if (columnObj.externally_triggered !== true) {
                $fromInput.add($toInput).on('dp.change', dateSelect);
            }
        } else if (columnObj.datepicker_type === 'bootstrap-datepicker') {
			//$fromInput.datepicker({});
			//$toInput.datepicker({});
		}

		if (oTable.fnSettings().oFeatures.bStateSave === true && oTable.fnSettings().oLoadedState) {
			if (oTable.fnSettings().oLoadedState.yadcfState && oTable.fnSettings().oLoadedState.yadcfState[table_selector_jq_friendly] && oTable.fnSettings().oLoadedState.yadcfState[table_selector_jq_friendly][column_number]) {
				$('#' + fromId).val(oTable.fnSettings().oLoadedState.yadcfState[table_selector_jq_friendly][column_number].from);
				if (oTable.fnSettings().oLoadedState.yadcfState[table_selector_jq_friendly][column_number].from !== "") {
					$('#' + fromId).addClass("inuse");
				}
				$('#' + toId).val(oTable.fnSettings().oLoadedState.yadcfState[table_selector_jq_friendly][column_number].to);
				if (oTable.fnSettings().oLoadedState.yadcfState[table_selector_jq_friendly][column_number].to !== "") {
					$('#' + toId).addClass("inuse");
				}
			}
		}

		if (oTable.fnSettings().oFeatures.bServerSide !== true) {
			addRangeDateFilterCapability(table_selector_jq_friendly, fromId, toId, column_number, date_format);
		}

		resetIApiIndex();
	}

	function addDateFilter(filter_selector_string, table_selector_jq_friendly, column_number, filter_reset_button_text, filter_default_label, date_format) {
		var dateId = "yadcf-filter-" + table_selector_jq_friendly + "-" + column_number,
			filter_selector_string_tmp,
			filter_wrapper_id,
			oTable,
			columnObj,
			datepickerObj = {},
			filterActionStr;

		filter_wrapper_id = "yadcf-filter-wrapper-" + table_selector_jq_friendly + "-" + column_number;

		if ($("#" + filter_wrapper_id).length > 0) {
			return;
		}
		$.fn.dataTableExt.iApiIndex = oTablesIndex[table_selector_jq_friendly];
		oTable = oTables[table_selector_jq_friendly];
		columnObj = getOptions(oTable.selector)[column_number];

		//add a wrapper to hold both filter and reset button
		$(filter_selector_string).append("<div onmousedown=\"yadcf.stopPropagation(event);\" onclick=\"yadcf.stopPropagation(event);\"  id=\"" + filter_wrapper_id + "\" class=\"yadcf-filter-wrapper\"></div>");
		filter_selector_string = filter_selector_string + " div.yadcf-filter-wrapper";
		filter_selector_string_tmp = filter_selector_string;

		filterActionStr = 'onkeyup="yadcf.dateKeyUP(\'' + table_selector_jq_friendly + '\',\'' + date_format + '\',event);"';
		if (columnObj.externally_triggered === true) {
			filterActionStr = '';
		}

		$(filter_selector_string).append("<input placeholder=\"" + filter_default_label + "\" id=\"" + dateId + "\" class=\"yadcf-filter-date\" " + filterActionStr + "></input>");

		if (filter_reset_button_text !== false) {
			$(filter_selector_string_tmp).append('<button type="button" id="' + dateId + '-reset" ' + 'onmousedown="yadcf.stopPropagation(event);" ' +
				'onclick="yadcf.stopPropagation(event);yadcf.dateSelectSingle(\'' + table_selector_jq_friendly + '\',yadcf.eventTargetFixUp(event).target, \'clear\'); return false;" class="yadcf-filter-reset-button">' + filter_reset_button_text + '</button>');
		}

	    if (columnObj.datepicker_type === 'jquery-ui') {
		    datepickerObj.dateFormat = date_format;
        } else if (columnObj.datepicker_type === 'bootstrap-datetimepicker') {
		    datepickerObj.format = date_format;
        }

		if (columnObj.externally_triggered !== true) {
			if (columnObj.datepicker_type === 'jquery-ui') {
				datepickerObj.onSelect = dateSelectSingle;
            }
		}

		datepickerObj = $.extend({}, columnObj.filter_plugin_options, datepickerObj);

		if (columnObj.datepicker_type === 'jquery-ui') {
            $("#" + dateId).datepicker(datepickerObj);
        } else if (columnObj.datepicker_type === 'bootstrap-datetimepicker') {
			datepickerObj.useCurrent = false;
            $("#" + dateId).datetimepicker(datepickerObj);
			if (columnObj.externally_triggered !== true) {
                $("#" + dateId).on('dp.change', dateSelectSingle);
            }
        } else if (columnObj.datepicker_type === 'bootstrap-datepicker') {
			$("#" + dateId).datepicker({});
		}

		if (oTable.fnSettings().aoPreSearchCols[column_number].sSearch !== '') {
			$('#yadcf-filter-' + table_selector_jq_friendly + '-' + column_number).val(oTable.fnSettings().aoPreSearchCols[column_number].sSearch).addClass("inuse");
		}

		resetIApiIndex();
	}

	function rangeNumberSldierDrawTips(min_tip_val, max_tip_val, min_tip_id, max_tip_id, table_selector_jq_friendly, column_number) {
		var first_handle = $("#yadcf-filter-wrapper-inner-" + table_selector_jq_friendly + "-" + column_number + " .ui-slider-handle:first"),
			last_handle = $("#yadcf-filter-wrapper-inner-" + table_selector_jq_friendly + "-" + column_number + " .ui-slider-handle:last"),
			min_tip_inner,
			max_tip_inner;

		min_tip_inner = "<div id=\"" + min_tip_id + "\" class=\"yadcf-filter-range-number-slider-min-tip-inner\">" + min_tip_val + "</div>";
		max_tip_inner = "<div id=\"" + max_tip_id + "\" class=\"yadcf-filter-range-number-slider-max-tip-inner\">" + max_tip_val + "</div>";

		$(first_handle).addClass("yadcf-filter-range-number-slider-min-tip").html(min_tip_inner);
		$(last_handle).addClass("yadcf-filter-range-number-slider-max-tip").html(max_tip_inner);
	}

	function rangeNumberSliderChange(table_selector_jq_friendly, event, ui) {
		event = eventTargetFixUp(event);
		var oTable,
			min_val,
			max_val,
			slider_inuse,
			yadcfState,
			column_number = $(event.target).attr('id').replace("yadcf-filter-", "").replace(table_selector_jq_friendly, "").replace("-slider-", ""),
			columnObj,
			keyUp;

		oTable = oTables[table_selector_jq_friendly];
		columnObj = getOptions(oTable.selector)[column_number];

		keyUp = function () {

			$.fn.dataTableExt.iApiIndex = oTablesIndex[table_selector_jq_friendly];

			if (oTable.fnSettings().oFeatures.bServerSide !== true) {
				oTable.fnDraw();
			} else {
				oTable.fnFilter(ui.values[0] + '-yadcf_delim-' + ui.values[1], column_number);
			}
			min_val = +$($(event.target).parent().find(".yadcf-filter-range-number-slider-min-tip-hidden")).text();
			max_val = +$($(event.target).parent().find(".yadcf-filter-range-number-slider-max-tip-hidden")).text();

			if (min_val !== ui.values[0]) {
				$($(event.target).find(".ui-slider-handle")[0]).addClass("inuse");
				slider_inuse = true;
			} else {
				$($(event.target).find(".ui-slider-handle")[0]).removeClass("inuse");
			}
			if (max_val !== ui.values[1]) {
				$($(event.target).find(".ui-slider-handle")[1]).addClass("inuse");
				slider_inuse = true;
			} else {
				$($(event.target).find(".ui-slider-handle")[1]).removeClass("inuse");
			}

			if (slider_inuse === true) {
				$(event.target).find(".ui-slider-range").addClass("inuse");
			} else {
				$(event.target).find(".ui-slider-range").removeClass("inuse");
			}

			if (!oTable.fnSettings().oLoadedState) {
				oTable.fnSettings().oLoadedState = {};
				oTable.fnSettings().oApi._fnSaveState(oTable.fnSettings());
			}
			if (oTable.fnSettings().oFeatures.bStateSave === true) {
				if (oTable.fnSettings().oLoadedState.yadcfState !== undefined && oTable.fnSettings().oLoadedState.yadcfState[table_selector_jq_friendly] !== undefined) {
					oTable.fnSettings().oLoadedState.yadcfState[table_selector_jq_friendly][column_number] =
						{
							'from' : ui.values[0],
							'to' : ui.values[1]
						};
				} else {
					yadcfState = {};
					yadcfState[table_selector_jq_friendly] = [];
					yadcfState[table_selector_jq_friendly][column_number] = {
						'from' : ui.values[0],
						'to' : ui.values[1]
					};
					oTable.fnSettings().oLoadedState.yadcfState = yadcfState;
				}
				oTable.fnSettings().oApi._fnSaveState(oTable.fnSettings());
			}

			resetIApiIndex();
		};

		if (columnObj.filter_delay === undefined) {
			keyUp();
		} else {
			yadcfDelay(function () {
				keyUp();
			}, columnObj.filter_delay);
		}
	}

	function addRangeNumberSliderFilter(filter_selector_string, table_selector_jq_friendly, column_number, filter_reset_button_text, min_val, max_val, ignore_char) {
		var sliderId = "yadcf-filter-" + table_selector_jq_friendly + "-slider-" + column_number,
			min_tip_id = "yadcf-filter-" + table_selector_jq_friendly + "-min_tip-" + column_number,
			max_tip_id = "yadcf-filter-" + table_selector_jq_friendly + "-max_tip-" + column_number,
			filter_selector_string_tmp,
			filter_wrapper_id,
			oTable,
			min_state_val = min_val,
			max_state_val = max_val,
			columnObj,
			slideFunc,
			changeFunc,
			sliderObj;

		filter_wrapper_id = "yadcf-filter-wrapper-" + table_selector_jq_friendly + "-" + column_number;

		if ($("#" + filter_wrapper_id).length > 0) {
			return;
		}

		$.fn.dataTableExt.iApiIndex = oTablesIndex[table_selector_jq_friendly];
		oTable = oTables[table_selector_jq_friendly];
		columnObj = getOptions(oTable.selector)[column_number];

		if (oTable.fnSettings().oFeatures.bStateSave === true && oTable.fnSettings().oLoadedState) {
			if (oTable.fnSettings().oLoadedState.yadcfState && oTable.fnSettings().oLoadedState.yadcfState[table_selector_jq_friendly] && oTable.fnSettings().oLoadedState.yadcfState[table_selector_jq_friendly][column_number]) {
				if (min_val !== oTable.fnSettings().oLoadedState.yadcfState[table_selector_jq_friendly][column_number].from) {
					min_state_val = oTable.fnSettings().oLoadedState.yadcfState[table_selector_jq_friendly][column_number].from;
				}
				if (max_val !== oTable.fnSettings().oLoadedState.yadcfState[table_selector_jq_friendly][column_number].to) {
					max_state_val = oTable.fnSettings().oLoadedState.yadcfState[table_selector_jq_friendly][column_number].to;
				}
			}
		}

		if (isFinite(min_val) && isFinite(max_val) && isFinite(min_state_val) && isFinite(max_state_val)) {

			//add a wrapper to hold both filter and reset button
			$(filter_selector_string).append("<div onmousedown=\"yadcf.stopPropagation(event);\" onclick=\"yadcf.stopPropagation(event);\"  id=\"" + filter_wrapper_id + "\" class=\"yadcf-filter-wrapper\"></div>");
			filter_selector_string = filter_selector_string + " div.yadcf-filter-wrapper";
			filter_selector_string_tmp = filter_selector_string;

			$(filter_selector_string).append("<div id=\"yadcf-filter-wrapper-inner-" + table_selector_jq_friendly + "-" + column_number + "\" class=\"yadcf-number-slider-filter-wrapper-inner\"></div>");
			filter_selector_string = filter_selector_string + " div.yadcf-number-slider-filter-wrapper-inner";

			$(filter_selector_string).append("<div id=\"" + sliderId + "\" class=\"yadcf-filter-range-number-slider\"></div>");
			filter_selector_string = filter_selector_string + " #" + sliderId;

			$(filter_selector_string).append("<span class=\"yadcf-filter-range-number-slider-min-tip-hidden hide\">" + min_val + "</span>");
			$(filter_selector_string).append("<span class=\"yadcf-filter-range-number-slider-max-tip-hidden hide\">" + max_val + "</span>");

			if (columnObj.externally_triggered !== true) {
				slideFunc = function (event, ui) {
					rangeNumberSldierDrawTips(ui.values[0], ui.values[1], min_tip_id, max_tip_id, table_selector_jq_friendly, column_number);
					rangeNumberSliderChange(table_selector_jq_friendly, event, ui);
				};
				changeFunc = function (event, ui) {
					rangeNumberSldierDrawTips(ui.values[0], ui.values[1], min_tip_id, max_tip_id, table_selector_jq_friendly, column_number);
					if (event.originalEvent || $(event.target).slider("option", "yadcf-reset") === true) {
						$(event.target).slider("option", "yadcf-reset", false);
						rangeNumberSliderChange(table_selector_jq_friendly, event, ui);
					}
				};
			} else {
				slideFunc = function (event, ui) {
					rangeNumberSldierDrawTips(ui.values[0], ui.values[1], min_tip_id, max_tip_id, table_selector_jq_friendly, column_number);
				};
				changeFunc = function (event, ui) {
					rangeNumberSldierDrawTips(ui.values[0], ui.values[1], min_tip_id, max_tip_id, table_selector_jq_friendly, column_number);
				};
			}
			sliderObj = {
				range: true,
				min: min_val,
				max: max_val,
				values: [min_state_val, max_state_val],
				create: function (event, ui) {
					rangeNumberSldierDrawTips(min_state_val, max_state_val, min_tip_id, max_tip_id, table_selector_jq_friendly, column_number);
				},
				slide: slideFunc,
				change: changeFunc
			};

			if (columnObj.filter_plugin_options !== undefined) {
				$.extend(sliderObj, columnObj.filter_plugin_options);
			}

			$("#" + sliderId).slider(sliderObj);

			if (filter_reset_button_text !== false) {
				$(filter_selector_string_tmp).append("<button type=\"button\" onmousedown=\"yadcf.stopPropagation(event);\" " +
					"onclick=\"yadcf.stopPropagation(event);yadcf.rangeNumberSliderClear('" + table_selector_jq_friendly + "',event); return false;\" class=\"yadcf-filter-reset-button range-number-slider-reset-button\">" + filter_reset_button_text + "</button>");
			}
		}

		$.fn.dataTableExt.iApiIndex = oTablesIndex[table_selector_jq_friendly];
		oTable = oTables[table_selector_jq_friendly];
		if (oTable.fnSettings().oFeatures.bStateSave === true && oTable.fnSettings().oLoadedState) {
			if (oTable.fnSettings().oLoadedState.yadcfState && oTable.fnSettings().oLoadedState.yadcfState[table_selector_jq_friendly] && oTable.fnSettings().oLoadedState.yadcfState[table_selector_jq_friendly][column_number]) {
				if (isFinite(min_val) && min_val !== oTable.fnSettings().oLoadedState.yadcfState[table_selector_jq_friendly][column_number].from) {
					$($(filter_selector_string).find(".ui-slider-handle")[0]).addClass("inuse");
				}
				if (isFinite(max_val) && max_val !== oTable.fnSettings().oLoadedState.yadcfState[table_selector_jq_friendly][column_number].to) {
					$($(filter_selector_string).find(".ui-slider-handle")[1]).addClass("inuse");
				}
				if ((isFinite(min_val) && isFinite(max_val)) && (min_val !== oTable.fnSettings().oLoadedState.yadcfState[table_selector_jq_friendly][column_number].from || max_val !== oTable.fnSettings().oLoadedState.yadcfState[table_selector_jq_friendly][column_number].to)) {
					$($(filter_selector_string).find(".ui-slider-range")).addClass("inuse");
				}
			}
		}
		resetIApiIndex();

		if (oTable.fnSettings().oFeatures.bServerSide !== true) {
			addRangeNumberAndSliderFilterCapability(table_selector_jq_friendly, min_tip_id, max_tip_id, column_number, ignore_char);
		}
	}

	function removeFilters(oTable, args, table_selector) {
		$('.yadcf-filter-wrapper').remove();
		if (yadcfVersionCheck('1.10')) {
			$(document).off('draw.dt', oTable.selector);
			$(document).off('xhr.dt', oTable.selector);
			$(document).off('column-visibility.dt', oTable.selector);
			$(document).off('destroy.dt', oTable.selector);
		} else {
			$(document).off('draw', oTable.selector);
			$(document).off('destroy', oTable.selector);
		}
	}

	function sortAlphaNum(a, b) {
		var aA = a.replace(reA, ""),
			bA = b.replace(reA, ""),
			aN,
			bN;
		if (aA === bA) {
			aN = parseInt(a.replace(reN, ""), 10);
			bN = parseInt(b.replace(reN, ""), 10);
			return aN === bN ? 0 : aN > bN ? 1 : -1;
		}
		return aA > bA ? 1 : -1;
	}

	function sortColumnData(column_data, columnObj) {
		var numArray = [],
			alphaArray = [];
		if (columnObj.filter_type === "select" || columnObj.filter_type === "auto_complete" || columnObj.filter_type === "multi_select" || columnObj.filter_type === 'multi_select_custom_func' || columnObj.filter_type === "custom_func") {
			if (columnObj.sort_as === "alpha") {
				if (columnObj.sort_order === "asc") {
					column_data.sort();
				} else if (columnObj.sort_order === "desc") {
					column_data.sort();
					column_data.reverse();
				}
			} else if (columnObj.sort_as === "num") {
				if (columnObj.sort_order === "asc") {
					column_data.sort(sortNumAsc);
				} else if (columnObj.sort_order === "desc") {
					column_data.sort(sortNumDesc);
				}
			} else if (columnObj.sort_as === "alphaNum") {
				if (columnObj.sort_order === "asc") {
					column_data.sort(sortAlphaNum);
				} else if (columnObj.sort_order === "desc") {
					column_data.sort(sortAlphaNum);
					column_data.reverse();
				}
			} else if (columnObj.sort_as === "custom") {
				column_data.sort(columnObj.sort_as_custom_func);
			}
		}
		return column_data;
	}
	function getFilteredRows(table) {
		var dataTmp,
			data = [],
			i;
		if (yadcfVersionCheck('1.10')) {
			dataTmp = table._('tr', {filter: 'applied' });
		} else {
			dataTmp = table.rows({filter: 'applied'}).data().toArray();
		}
		for (i = 0; i < dataTmp.length; i++) {
			data.push({
				_aData: dataTmp[i]
			});
		}
		return data;
	}

	function parseTableColumn(pTable, columnObj, table_selector_jq_friendly) {
		var col_inner_elements,
			col_inner_data,
			j,
			k,
			col_filter_array = {},
			column_data = [],
			data,
			data_length,
			settingsDt,
			column_number_filter;

		settingsDt = getSettingsObjFromTable(pTable);

		if (columnObj.cumulative_filtering !== true) {
			data = settingsDt.aoData;
			data_length = data.length;
		} else {
			data = getFilteredRows(pTable);
			data_length = data.length;
		}
		if (columnObj.col_filter_array !== undefined) {
			col_filter_array = columnObj.col_filter_array;
		}
		column_number_filter = calcColumnNumberFilter(settingsDt, columnObj.column_number, table_selector_jq_friendly);
		if (isNaN(settingsDt.aoColumns[column_number_filter].mData) && typeof settingsDt.aoColumns[column_number_filter].mData !== 'object') {
			columnObj.column_number_data = settingsDt.aoColumns[column_number_filter].mData;
		}

		for (j = 0; j < data_length; j++) {
			if (columnObj.column_data_type === "html") {
				if (columnObj.column_number_data === undefined) {
					col_inner_elements = $(data[j]._aData[column_number_filter]);
				} else {
					col_inner_elements = dot2obj(data[j]._aData, columnObj.column_number_data);
					col_inner_elements = $(col_inner_elements);
				}
				if (col_inner_elements.length > 0) {
					for (k = 0; k < col_inner_elements.length; k++) {
						switch (columnObj.html_data_type) {
						case "text":
							col_inner_data = $(col_inner_elements[k]).text();
							break;
						case "value":
							col_inner_data = $(col_inner_elements[k]).val();
							break;
						case "id":
							col_inner_data = col_inner_elements[k].id;
							break;
						case "selector":
							col_inner_data = $(col_inner_elements[k]).find(columnObj.html_data_selector).text();
							break;
						}

						if ($.trim(col_inner_data) !== '' && !(col_filter_array.hasOwnProperty(col_inner_data))) {
							col_filter_array[col_inner_data] = col_inner_data;
							column_data.push(col_inner_data);
						}
					}
				} else {
					col_inner_data = col_inner_elements.selector;
					if ($.trim(col_inner_data) !== '' && !(col_filter_array.hasOwnProperty(col_inner_data))) {
						col_filter_array[col_inner_data] = col_inner_data;
						column_data.push(col_inner_data);
					}
				}

			} else if (columnObj.column_data_type === "text") {
				if (columnObj.text_data_delimiter !== undefined) {
					if (columnObj.column_number_data === undefined) {
						col_inner_elements = data[j]._aData[column_number_filter].split(columnObj.text_data_delimiter);
					} else {
						col_inner_elements = dot2obj(data[j]._aData, columnObj.column_number_data);
						col_inner_elements = (col_inner_elements + '').split(columnObj.text_data_delimiter);
					}
					for (k = 0; k < col_inner_elements.length; k++) {
						col_inner_data = col_inner_elements[k];
						if ($.trim(col_inner_data) !== '' && !(col_filter_array.hasOwnProperty(col_inner_data))) {
							col_filter_array[col_inner_data] = col_inner_data;
							column_data.push(col_inner_data);
						}
					}
				} else {
					if (columnObj.column_number_data === undefined) {
						col_inner_data = data[j]._aData[column_number_filter];
						if (typeof col_inner_data === 'object') {
							if (columnObj.html5_data !== undefined) {
								col_inner_data = col_inner_data['@' + columnObj.html5_data];
							} else {
								alert('Looks like you have forgot to define the html5_data attribute for the ' + columnObj.column_number + ' column');
								return;
							}
						}
					} else if (data[j]._aFilterData !== undefined && data[j]._aFilterData !== null) {
						col_inner_data = data[j]._aFilterData[column_number_filter];
					} else {
						col_inner_data = dot2obj(data[j]._aData, columnObj.column_number_data);
					}
					if ($.trim(col_inner_data) !== '' && !(col_filter_array.hasOwnProperty(col_inner_data))) {
						col_filter_array[col_inner_data] = col_inner_data;
						column_data.push(col_inner_data);
					}
				}
			} else if (columnObj.column_data_type === "rendered_html") {
				col_inner_elements = data[j]._aFilterData[column_number_filter];
				col_inner_elements = $(col_inner_elements);
				if (col_inner_elements.length > 0) {
					for (k = 0; k < col_inner_elements.length; k++) {
						switch (columnObj.html_data_type) {
						case "text":
							col_inner_data = $(col_inner_elements[k]).text();
							break;
						case "value":
							col_inner_data = $(col_inner_elements[k]).val();
							break;
						case "id":
							col_inner_data = col_inner_elements[k].id;
							break;
						case "selector":
							col_inner_data = $(col_inner_elements[k]).find(columnObj.html_data_selector).text();
							break;
						}
					}
				} else {
					col_inner_data = col_inner_elements.selector;
				}
				if ($.trim(col_inner_data) !== '' && !(col_filter_array.hasOwnProperty(col_inner_data))) {
					col_filter_array[col_inner_data] = col_inner_data;
					column_data.push(col_inner_data);
				}
			}
		}
		columnObj.col_filter_array = col_filter_array;
		return column_data;
	}

	function appendFilters(oTable, args, table_selector) {

		var i = 0,
			$filter_selector,
			filter_selector_string,

			data,
			filter_container_id,
			column_number_data,
			column_number,
			column_position,
			column_data_type,
			html_data_type,
			text_data_delimiter,
			filter_default_label,
			filter_reset_button_text,
			enable_auto_complete,
			sort_as,
			sort_order,
			date_format,
			ignore_char,
			filter_match_mode,

			column_data,
			column_data_temp,
			options_tmp,
			j,
			k,
			data_length,
			col_inner_elements,
			col_inner_data,
			ii,
			table_selector_jq_friendly,
			min_val,
			max_val,
			col_num_visible,
			col_num_visible_iter,
			tmpStr,
			columnObjKey,
			columnObj,
			filters_position,
			unique_th,
			settingsDt,
			filterActionStr,
			custom_func_filter_value_holder,
			exclude_str,
			tableDT,
			columnFilterVal;

		settingsDt = getSettingsObjFromTable(oTable);
		table_selector_jq_friendly = yadcf.generateTableSelectorJQFriendly(table_selector);
		tableDT = tablesDT[table_selector_jq_friendly];

		initColReorder2(settingsDt, table_selector_jq_friendly);

		filters_position = $(document).data(table_selector + "_filters_position");
		if (settingsDt.oScroll.sX !== '' || settingsDt.oScroll.sY !== '') {
			table_selector = '.yadcf-datatables-table-' + table_selector_jq_friendly;
		}
		if (oTable._fnGetUniqueThs() !== undefined) {
			unique_th = oTable._fnGetUniqueThs();
		}
		for (columnObjKey in args) {
			if (args.hasOwnProperty(columnObjKey)) {
				columnObj = args[columnObjKey];

				options_tmp = '';
				tmpStr = '';
				data = columnObj.data;
				column_data = [];
				column_data_temp = [];
				filter_container_id = columnObj.filter_container_id;
				column_number = columnObj.column_number;
				column_number = +column_number;
				column_position = column_number;

				if (plugins[table_selector_jq_friendly] !== undefined && (plugins[table_selector_jq_friendly] !== undefined && plugins[table_selector_jq_friendly].ColReorder !== undefined)) {
					column_position = plugins[table_selector_jq_friendly].ColReorder[column_number];
				}

				columnObj.column_number = column_number;
				column_number_data = undefined;
				if (isNaN(settingsDt.aoColumns[column_position].mData) && typeof settingsDt.aoColumns[column_position].mData !== 'object') {
					column_number_data = settingsDt.aoColumns[column_position].mData;
					columnObj.column_number_data = column_number_data;
				}
				column_data_type = columnObj.column_data_type;
				html_data_type = columnObj.html_data_type;
				text_data_delimiter = columnObj.text_data_delimiter;
				filter_default_label = columnObj.filter_default_label;
				filter_reset_button_text = columnObj.filter_reset_button_text;
				enable_auto_complete = columnObj.enable_auto_complete;
				sort_as = columnObj.sort_as;
				sort_order = columnObj.sort_order;
				date_format = columnObj.date_format;
				//for jquery datepicker
				date_format = date_format.replace("yyyy", "yy");
				columnObj.date_format = date_format;

				if (columnObj.ignore_char !== undefined && !(columnObj.ignore_char instanceof RegExp)) {
					ignore_char = new RegExp(columnObj.ignore_char, "g");
					columnObj.ignore_char = ignore_char;
				}
				filter_match_mode = columnObj.filter_match_mode;

				if (column_number === undefined) {
					alert("You must specify column number");
					return;
				}



				if (enable_auto_complete === true) {
					columnObj.filter_type = "auto_complete";
				}

				if (filter_default_label === undefined) {
					if (columnObj.filter_type === "select" || columnObj.filter_type === 'custom_func') {
						filter_default_label = "Select value";
					} else if (columnObj.filter_type === "multi_select" || columnObj.filter_type === 'multi_select_custom_func') {
						filter_default_label = "Select values";
					} else if (columnObj.filter_type === "auto_complete" || columnObj.filter_type === "text") {
						filter_default_label = 'Type to filter';
					} else if (columnObj.filter_type === "range_number" || columnObj.filter_type === "range_date") {
						filter_default_label = ["from", "to"];
					} else if (columnObj.filter_type === "date") {
						filter_default_label = "Select a date";
					}
					columnObj.filter_default_label = filter_default_label;
				}

				if (filter_reset_button_text === undefined) {
					filter_reset_button_text = "x";
				}

				if (data !== undefined) {
					for (ii = 0; ii < data.length; ii++) {
						column_data.push(data[ii]);
					}
				}
				if (data === undefined || columnObj.append_data_to_table_data !== undefined) {
					columnObj.col_filter_array = undefined;
					column_data_temp = parseTableColumn(oTable, columnObj, table_selector_jq_friendly);
					if (columnObj.append_data_to_table_data !== 'before') {
						column_data = column_data.concat(column_data_temp);
					} else {
						column_data_temp = sortColumnData(column_data_temp, columnObj);
						column_data = column_data.concat(column_data_temp);
					}
				}

				if (columnObj.append_data_to_table_data === undefined || columnObj.append_data_to_table_data === 'sorted') {
					column_data = sortColumnData(column_data, columnObj);
				}

				if (columnObj.filter_type === "range_number_slider") {
					min_val = findMinInArray(column_data, columnObj);
					max_val = findMaxInArray(column_data, columnObj);
				}


				if (filter_container_id === undefined) {
					//Can't show filter inside a column for a hidden one (place it outside using filter_container_id)
					if (settingsDt.aoColumns[column_position].bVisible === false) {
						//console.log('Yadcf warning: Can\'t show filter inside a column N#' + column_number + ' for a hidden one (place it outside using filter_container_id)');
						continue;
					}

					if (filters_position !== 'thead') {
						if (unique_th === undefined) {
							//handle hidden columns
							col_num_visible = column_position;
							for (col_num_visible_iter = 0; col_num_visible_iter < settingsDt.aoColumns.length && col_num_visible_iter < column_position; col_num_visible_iter++) {
								if (settingsDt.aoColumns[col_num_visible_iter].bVisible === false) {
									col_num_visible--;
								}
							}
							column_position = col_num_visible;
							filter_selector_string = table_selector + ' ' + filters_position + ' th:eq(' + column_position + ')';
						} else {
							filter_selector_string = table_selector + ' ' + filters_position + ' th:eq(' + $(unique_th[column_position]).index() + ')';
						}
					} else {
						filter_selector_string = table_selector + ' ' + filters_position + ' tr:eq(' + $(unique_th[column_position]).parent().index() + ') th:eq(' + $(unique_th[column_position]).index() + ')';
					}
					$filter_selector = $(filter_selector_string).find(".yadcf-filter");
				} else {
					if ($("#" + filter_container_id).length === 0) {
						alert("Filter container could not be found.");
						return;
					}
					filter_selector_string = "#" + filter_container_id;
					$filter_selector = $(filter_selector_string).find(".yadcf-filter");
				}


				if (columnObj.filter_type === "select" || columnObj.filter_type === 'custom_func' || columnObj.filter_type === "multi_select" || columnObj.filter_type === 'multi_select_custom_func') {
					if (columnObj.filter_type === "select" || columnObj.filter_type === 'custom_func') {
						options_tmp = "<option value=\"" + "-1" + "\">" + filter_default_label + "</option>";

						if (columnObj.select_type === 'select2' && columnObj.select_type_options.placeholder !== undefined && columnObj.select_type_options.allowClear === true) {
							options_tmp = "<option value=\"\"></option>";
						}
					} else if (columnObj.filter_type === "multi_select" || columnObj.filter_type === 'multi_select_custom_func') {
						if (columnObj.select_type === undefined) {
							options_tmp = "<option data-placeholder=\"true\" value=\"" + "-1" + "\">" + filter_default_label + "</option>";
						} else {
							options_tmp = "";
						}
					}

					if (columnObj.append_data_to_table_data === undefined) {
						if (typeof column_data[0] === 'object') {
							for (ii = 0; ii < column_data.length; ii++) {
								options_tmp += "<option value=\"" + column_data[ii].value + "\">" + column_data[ii].label + "</option>";
							}
						} else {
							for (ii = 0; ii < column_data.length; ii++) {
								options_tmp += "<option value=\"" + column_data[ii] + "\">" + column_data[ii] + "</option>";
							}
						}
					} else {
						for (ii = 0; ii < column_data.length; ii++) {
							if (typeof column_data[ii] === 'object') {
								options_tmp += "<option value=\"" + column_data[ii].value + "\">" + column_data[ii].label + "</option>";
							} else {
								options_tmp += "<option value=\"" + column_data[ii] + "\">" + column_data[ii] + "</option>";
							}
						}
					}
					column_data = options_tmp;
				}
				if ($filter_selector.length === 1) {
					if (columnObj.filter_type === "select" || columnObj.filter_type === "multi_select" || columnObj.filter_type === 'custom_func' || columnObj.filter_type === 'multi_select_custom_func') {
						if (columnObj.filter_type === 'custom_func' || columnObj.filter_type === 'multi_select_custom_func') {
							custom_func_filter_value_holder = $('#yadcf-filter-' + table_selector_jq_friendly + '-' + column_number).val();
						}
						$filter_selector.empty();
						$filter_selector.append(column_data);
						if (settingsDt.aoPreSearchCols[column_position].sSearch !== '') {
							tmpStr = settingsDt.aoPreSearchCols[column_position].sSearch;
							if (columnObj.filter_type === "select") {
								tmpStr = yadcfParseMatchFilter(tmpStr, getOptions(oTable.selector)[column_number].filter_match_mode);
								$('#yadcf-filter-' + table_selector_jq_friendly + '-' + column_number).val(tmpStr).addClass("inuse");
							} else if (columnObj.filter_type === "multi_select") {
								tmpStr = yadcfParseMatchFilterMultiSelect(tmpStr, getOptions(oTable.selector)[column_number].filter_match_mode);
								tmpStr = tmpStr.replace(/\\/g, "");
								tmpStr = tmpStr.split("|");
								$('#yadcf-filter-' + table_selector_jq_friendly + '-' + column_number).val(tmpStr);
							}
						}
						if (columnObj.filter_type === 'custom_func' || columnObj.filter_type === 'multi_select_custom_func') {
							tmpStr = custom_func_filter_value_holder;
							if (tmpStr === '-1' || tmpStr === undefined) {
								$('#yadcf-filter-' + table_selector_jq_friendly + '-' + column_number).val(tmpStr);
							} else {
								$('#yadcf-filter-' + table_selector_jq_friendly + '-' + column_number).val(tmpStr).addClass("inuse");
							}
						}

						initializeSelectPlugin(columnObj.select_type, $("#yadcf-filter-" + table_selector_jq_friendly + "-" + column_number), columnObj.select_type_options);

					} else if (columnObj.filter_type === "auto_complete") {
						$(document).data("yadcf-filter-" + table_selector_jq_friendly + "-" + column_number, column_data);
					}
				} else {
					if (filter_container_id === undefined) {
						if ($(filter_selector_string + " div.DataTables_sort_wrapper").length > 0) {
							$(filter_selector_string + " div.DataTables_sort_wrapper").css("display", "inline-block");
						}
					} else {
						if ($("#yadcf-filter-wrapper-" + filter_container_id).length === 0) {
							$("#" + filter_container_id).append("<div id=\"yadcf-filter-wrapper-" + filter_container_id + "\"></div>");
						}
						filter_selector_string = "#yadcf-filter-wrapper-" + filter_container_id;
					}

					if (columnObj.filter_type === "select" || columnObj.filter_type === 'custom_func') {

						//add a wrapper to hold both filter and reset button
						$(filter_selector_string).append("<div id=\"yadcf-filter-wrapper-" + table_selector_jq_friendly + "-" + column_number + "\" class=\"yadcf-filter-wrapper\"></div>");
						filter_selector_string = filter_selector_string + " div.yadcf-filter-wrapper";

						if (columnObj.filter_type === "select") {
							filterActionStr = 'onchange="yadcf.doFilter(this, \'' + table_selector_jq_friendly + '\', ' + column_number + ', \'' + filter_match_mode + '\');"';
							if (columnObj.externally_triggered === true) {
								filterActionStr = '';
							}
							$(filter_selector_string).append("<select id=\"yadcf-filter-" + table_selector_jq_friendly + "-" + column_number + "\" class=\"yadcf-filter " + columnObj.style_class + "\" " +
								filterActionStr + " onmousedown=\"yadcf.stopPropagation(event);\" onclick='yadcf.stopPropagation(event);'>" + column_data + "</select>");
							if (filter_reset_button_text !== false) {
								$(filter_selector_string).find(".yadcf-filter").after("<button type=\"button\" " +
									"id=\"yadcf-filter-" + table_selector_jq_friendly + "-" + column_number + "-reset\" onmousedown=\"yadcf.stopPropagation(event);\" onclick=\"yadcf.stopPropagation(event);yadcf.doFilter('clear', '" + table_selector_jq_friendly + "', " + column_number + "); return false;\" class=\"yadcf-filter-reset-button\">" + filter_reset_button_text + "</button>");
							}
						} else {
							filterActionStr = 'onchange="yadcf.doFilterCustomDateFunc(this, \'' + table_selector_jq_friendly  + '\', ' +  column_number + ');"';
							if (columnObj.externally_triggered === true) {
								filterActionStr = '';
							}
							$(filter_selector_string).append("<select id=\"yadcf-filter-" + table_selector_jq_friendly + "-" + column_number + "\" class=\"yadcf-filter " + columnObj.style_class + "\" " +
								filterActionStr	+ " onmousedown=\"yadcf.stopPropagation(event);\" onclick='yadcf.stopPropagation(event);'>" + column_data + "</select>");
							if (filter_reset_button_text !== false) {
								$(filter_selector_string).find(".yadcf-filter").after("<button type=\"button\" onmousedown=\"yadcf.stopPropagation(event);\" " +
									"onclick=\"yadcf.stopPropagation(event);yadcf.doFilterCustomDateFunc('clear', '" + table_selector_jq_friendly + "', " + column_number + "); return false;\" class=\"yadcf-filter-reset-button\">" + filter_reset_button_text + "</button>");
							}

							if (settingsDt.oFeatures.bStateSave === true && settingsDt.oLoadedState) {
								if (settingsDt.oLoadedState.yadcfState && settingsDt.oLoadedState.yadcfState[table_selector_jq_friendly] && settingsDt.oLoadedState.yadcfState[table_selector_jq_friendly][column_number]) {
									tmpStr = settingsDt.oLoadedState.yadcfState[table_selector_jq_friendly][column_number].from;
									if (tmpStr === '-1' || tmpStr === undefined) {
										$('#yadcf-filter-' + table_selector_jq_friendly + '-' + column_number).val(tmpStr);
									} else {
										$('#yadcf-filter-' + table_selector_jq_friendly + '-' + column_number).val(tmpStr).addClass("inuse");
									}
								}
							}
							if (settingsDt.oFeatures.bServerSide !== true) {
								addCustomFunctionFilterCapability(table_selector_jq_friendly, "yadcf-filter-" + table_selector_jq_friendly + "-" + column_number, column_number);
							}
						}

						if (settingsDt.aoPreSearchCols[column_position].sSearch !== '') {
							tmpStr = settingsDt.aoPreSearchCols[column_position].sSearch;
							tmpStr = yadcfParseMatchFilter(tmpStr, getOptions(oTable.selector)[column_number].filter_match_mode);
							$('#yadcf-filter-' + table_selector_jq_friendly + '-' + column_number).val(tmpStr).addClass("inuse");
						}

						if (columnObj.select_type !== undefined) {
							initializeSelectPlugin(columnObj.select_type, $("#yadcf-filter-" + table_selector_jq_friendly + "-" + column_number), columnObj.select_type_options);
						}

					} else if (columnObj.filter_type === "multi_select" || columnObj.filter_type === 'multi_select_custom_func') {

						//add a wrapper to hold both filter and reset button
						$(filter_selector_string).append("<div id=\"yadcf-filter-wrapper-" + table_selector_jq_friendly + "-" + column_number + "\" class=\"yadcf-filter-wrapper\"></div>");
						filter_selector_string = filter_selector_string + " div.yadcf-filter-wrapper";

						if (columnObj.filter_type === "multi_select") {
							filterActionStr = 'onchange="yadcf.doFilterMultiSelect(this, \'' + table_selector_jq_friendly + '\', ' + column_number + ', \'' + filter_match_mode + '\');"';
							if (columnObj.externally_triggered === true) {
								filterActionStr = '';
							}
							$(filter_selector_string).append("<select multiple data-placeholder=\"" + filter_default_label + "\" id=\"yadcf-filter-" + table_selector_jq_friendly + "-" + column_number + "\" class=\"yadcf-filter " + columnObj.style_class + "\" " +
								filterActionStr	+ " onmousedown=\"yadcf.stopPropagation(event);\" onclick='yadcf.stopPropagation(event);'>" + column_data + "</select>");

							if (filter_reset_button_text !== false) {
								$(filter_selector_string).find(".yadcf-filter").after("<button type=\"button\" onmousedown=\"yadcf.stopPropagation(event);\" " +
									"onclick=\"yadcf.stopPropagation(event);yadcf.doFilter('clear', '" + table_selector_jq_friendly + "', " + column_number + "); return false;\" class=\"yadcf-filter-reset-button\">" + filter_reset_button_text + "</button>");
							}

							if (settingsDt.aoPreSearchCols[column_position].sSearch !== '') {
								tmpStr = settingsDt.aoPreSearchCols[column_position].sSearch;
								tmpStr = yadcfParseMatchFilterMultiSelect(tmpStr, getOptions(oTable.selector)[column_number].filter_match_mode);
								tmpStr = tmpStr.replace(/\\/g, "");
								tmpStr = tmpStr.split("|");
								$('#yadcf-filter-' + table_selector_jq_friendly + '-' + column_number).val(tmpStr);
							}
						} else {
							filterActionStr = 'onchange="yadcf.doFilterCustomDateFunc(this, \'' + table_selector_jq_friendly + '\', ' + column_number + ');"';
							if (columnObj.externally_triggered === true) {
								filterActionStr = '';
							}
							$(filter_selector_string).append("<select multiple data-placeholder=\"" + filter_default_label + "\" id=\"yadcf-filter-" + table_selector_jq_friendly + "-" + column_number + "\" class=\"yadcf-filter " + columnObj.style_class + "\" " +
								filterActionStr	+ " onmousedown=\"yadcf.stopPropagation(event);\" onclick='yadcf.stopPropagation(event);'>" + column_data + "</select>");

							if (filter_reset_button_text !== false) {
								$(filter_selector_string).find(".yadcf-filter").after("<button type=\"button\" onmousedown=\"yadcf.stopPropagation(event);\" " +
									"onclick=\"yadcf.stopPropagation(event);yadcf.doFilterCustomDateFunc('clear', '" + table_selector_jq_friendly + "', " + column_number + "); return false;\" class=\"yadcf-filter-reset-button\">" + filter_reset_button_text + "</button>");
							}

							if (settingsDt.oFeatures.bStateSave === true && settingsDt.oLoadedState) {
								if (settingsDt.oLoadedState.yadcfState && settingsDt.oLoadedState.yadcfState[table_selector_jq_friendly] && settingsDt.oLoadedState.yadcfState[table_selector_jq_friendly][column_number]) {
									tmpStr = settingsDt.oLoadedState.yadcfState[table_selector_jq_friendly][column_number].from;
									if (tmpStr === '-1' || tmpStr === undefined) {
										$('#yadcf-filter-' + table_selector_jq_friendly + '-' + column_number).val(tmpStr);
									} else {
										$('#yadcf-filter-' + table_selector_jq_friendly + '-' + column_number).val(tmpStr).addClass("inuse");
									}
								}
							}
							if (settingsDt.oFeatures.bServerSide !== true) {
								addCustomFunctionFilterCapability(table_selector_jq_friendly, "yadcf-filter-" + table_selector_jq_friendly + "-" + column_number, column_number);
							}
						}

						if (columnObj.filter_container_id === undefined && columnObj.select_type_options.width === undefined) {
							columnObj.select_type_options = $.extend(columnObj.select_type_options, {width: $(filter_selector_string).closest("th").width() + "px"});
						}
						if (columnObj.filter_container_id !== undefined && columnObj.select_type_options.width === undefined) {
							columnObj.select_type_options = $.extend(columnObj.select_type_options, {width: $(filter_selector_string).closest('#' + columnObj.filter_container_id).width() + "px"});
						}

						if (columnObj.select_type !== undefined) {
							initializeSelectPlugin(columnObj.select_type, $("#yadcf-filter-" + table_selector_jq_friendly + "-" + column_number), columnObj.select_type_options);
						}

					} else if (columnObj.filter_type === "auto_complete") {

						//add a wrapper to hold both filter and reset button
						$(filter_selector_string).append("<div id=\"yadcf-filter-wrapper-" + table_selector_jq_friendly + "-" + column_number + "\" class=\"yadcf-filter-wrapper\"></div>");
						filter_selector_string = filter_selector_string + " div.yadcf-filter-wrapper";

						filterActionStr = 'onkeyup="yadcf.autocompleteKeyUP(\'' + table_selector_jq_friendly + '\',event);"';
						if (columnObj.externally_triggered === true) {
							filterActionStr = '';
						}
						$(filter_selector_string).append("<input id=\"yadcf-filter-" + table_selector_jq_friendly + "-" + column_number + "\" class=\"yadcf-filter\" onmousedown=\"yadcf.stopPropagation(event);\" onclick='yadcf.stopPropagation(event);"
							+ "' placeholder='" + filter_default_label + "'" + " filter_match_mode='" + filter_match_mode + "' " + filterActionStr + "></input>");
						$(document).data("yadcf-filter-" + table_selector_jq_friendly + "-" + column_number, column_data);

						if (filter_reset_button_text !== false) {
							$(filter_selector_string).find(".yadcf-filter").after("<button type=\"button\" onmousedown=\"yadcf.stopPropagation(event);\" " +
								"onclick=\"yadcf.stopPropagation(event);yadcf.doFilterAutocomplete('clear', '" + table_selector_jq_friendly + "', " + column_number + "); return false;\" class=\"yadcf-filter-reset-button\">" + filter_reset_button_text + "</button>");
						}

					} else if (columnObj.filter_type === "text") {

						//add a wrapper to hold both filter and reset button
						$(filter_selector_string).append("<div id=\"yadcf-filter-wrapper-" + table_selector_jq_friendly + "-" + column_number + "\" class=\"yadcf-filter-wrapper\"></div>");
						filter_selector_string = filter_selector_string + " div.yadcf-filter-wrapper";

						filterActionStr = 'onkeyup="yadcf.textKeyUP(\'' + table_selector_jq_friendly + '\', ' + column_number + ');"';
						if (columnObj.externally_triggered === true) {
							filterActionStr = '';
						}

						exclude_str = '';
						if (columnObj.exclude === true) {
							exclude_str = '<span class="yadcf-exclude-wrapper" onmousedown="yadcf.stopPropagation(event);" onclick="yadcf.stopPropagation(event);">' +
								'<div class="yadcf-label small">' + columnObj.exclude_label + '</div><input type="checkbox" title="' + columnObj.exclude_label + '" onclick="yadcf.stopPropagation(event);yadcf.textKeyUP(\'' + table_selector_jq_friendly + '\',' + column_number + ');"></span>';
						}

						$(filter_selector_string).append(exclude_str + "<input type=\"text\" id=\"yadcf-filter-" + table_selector_jq_friendly + "-" + column_number + "\" class=\"yadcf-filter " + columnObj.style_class + "\" onmousedown=\"yadcf.stopPropagation(event);\" onclick='yadcf.stopPropagation(event);"
							+ "' placeholder='" + filter_default_label + "'" + " filter_match_mode='" + filter_match_mode + "' " + filterActionStr + "></input>");

						if (filter_reset_button_text !== false) {
							$(filter_selector_string).find(".yadcf-filter").after("<button type=\"button\" " + " id=\"yadcf-filter-" + table_selector_jq_friendly + "-" + column_number + "-reset\" onmousedown=\"yadcf.stopPropagation(event);\" " +
								"onclick=\"yadcf.stopPropagation(event);yadcf.textKeyUP('" + table_selector_jq_friendly + "', '" + column_number + "', 'clear'); return false;\" class=\"yadcf-filter-reset-button\">" + filter_reset_button_text + "</button>");
						}

						if (settingsDt.aoPreSearchCols[column_position].sSearch !== '') {
							tmpStr = settingsDt.aoPreSearchCols[column_position].sSearch;
							if (columnObj.exclude === true) {
								if (tmpStr.indexOf('^((?!') !== -1) {
									$('#yadcf-filter-wrapper-' + table_selector_jq_friendly + '-' + column_number).find(':checkbox').prop('checked', true);
								}
								tmpStr = tmpStr.substring(5, tmpStr.indexOf(').)'));
							}
							tmpStr = yadcfParseMatchFilter(tmpStr, getOptions(oTable.selector)[column_number].filter_match_mode);
							$('#yadcf-filter-' + table_selector_jq_friendly + '-' + column_number).val(tmpStr).addClass("inuse");
						}

					} else if (columnObj.filter_type === "date") {

						addDateFilter(filter_selector_string, table_selector_jq_friendly, column_number, filter_reset_button_text, filter_default_label, date_format);

					} else if (columnObj.filter_type === "range_number") {

						addRangeNumberFilter(filter_selector_string, table_selector_jq_friendly, column_number, filter_reset_button_text, filter_default_label, ignore_char);

					} else if (columnObj.filter_type === "range_number_slider") {

						addRangeNumberSliderFilter(filter_selector_string, table_selector_jq_friendly, column_number, filter_reset_button_text, min_val, max_val, ignore_char);

					} else if (columnObj.filter_type === "range_date") {

						addRangeDateFilter(filter_selector_string, table_selector_jq_friendly, column_number, filter_reset_button_text, filter_default_label, date_format);

					}
				}

				if ($(document).data("#yadcf-filter-" + table_selector_jq_friendly + "-" + column_number + "_val") !== undefined && $(document).data("#yadcf-filter-" + table_selector_jq_friendly + "-" + column_number + "_val") !== "-1") {
					$(filter_selector_string).find(".yadcf-filter").val($(document).data("#yadcf-filter-" + table_selector_jq_friendly + "-" + column_number + "_val"));
				}
				if (columnObj.filter_type === "auto_complete") {
					if (columnObj.filter_plugin_options !== undefined) {
						columnObj.filter_plugin_options.source = $(document).data("yadcf-filter-" + table_selector_jq_friendly + "-" + column_number);
						columnObj.filter_plugin_options.select = autocompleteSelect;
					} else {
						columnObj.filter_plugin_options = {
							source: $(document).data("yadcf-filter-" + table_selector_jq_friendly + "-" + column_number),
							select: autocompleteSelect
						};
					}
					if (columnObj.externally_triggered === true) {
						delete columnObj.filter_plugin_options.select;
					}
					$("#yadcf-filter-" + table_selector_jq_friendly + "-" + column_number).autocomplete(columnObj.filter_plugin_options);
					if (settingsDt.aoPreSearchCols[column_position].sSearch !== '') {
						tmpStr = settingsDt.aoPreSearchCols[column_position].sSearch;
						tmpStr = yadcfParseMatchFilter(tmpStr, getOptions(oTable.selector)[column_number].filter_match_mode);
						$('#yadcf-filter-' + table_selector_jq_friendly + '-' + column_number).val(tmpStr).addClass("inuse");
					}
				}
			}
		}
		if (exFilterColumnQueue.length > 0) {
			(exFilterColumnQueue.shift())();
		}
	}

	function endsWith(str, suffix) {
		return str.indexOf(suffix, str.length - suffix.length) !== -1;
	}

	function rangeClear(table_selector_jq_friendly, event) {
		event = eventTargetFixUp(event);
		$.fn.dataTableExt.iApiIndex = oTablesIndex[table_selector_jq_friendly];
		var oTable = oTables[table_selector_jq_friendly],
			yadcfState,
			settingsDt,
			column_number,
			column_number_filter,
			currentFilterValues,
			columnObj;

		settingsDt = getSettingsObjFromTable(oTable);
		column_number = parseInt($(event.target).parent().attr("id").replace('yadcf-filter-wrapper-' + table_selector_jq_friendly + '-', ''), 10);

		column_number_filter = calcColumnNumberFilter(settingsDt, column_number, table_selector_jq_friendly);

		currentFilterValues = exGetColumnFilterVal(oTable, column_number);
		if (currentFilterValues.from === '' && currentFilterValues.to === '') {
			return;
		}

		columnObj = getOptions(oTable.selector)[column_number];
		if (columnObj.filter_type === 'range_date' && columnObj.datepicker_type === 'bootstrap-datetimepicker') {
			$($(event.target).parent().find(".yadcf-filter-range")[0]).data("DateTimePicker").maxDate(false);
			$($(event.target).parent().find(".yadcf-filter-range")[1]).data("DateTimePicker").minDate(false);
		}

		$(event.target).parent().find(".yadcf-filter-range").val("");
		if ($(event.target).parent().find(".yadcf-filter-range-number").length > 0) {
			$($(event.target).parent().find(".yadcf-filter-range")[0]).focus();
		}

		if (oTable.fnSettings().oFeatures.bServerSide !== true) {
			oTable.fnDraw();
		} else {
			oTable.fnFilter('-yadcf_delim-', column_number_filter);
		}

		if (!oTable.fnSettings().oLoadedState) {
			oTable.fnSettings().oLoadedState = {};
			oTable.fnSettings().oApi._fnSaveState(oTable.fnSettings());
		}
		if (oTable.fnSettings().oFeatures.bStateSave === true) {
			if (oTable.fnSettings().oLoadedState.yadcfState !== undefined && oTable.fnSettings().oLoadedState.yadcfState[table_selector_jq_friendly] !== undefined) {
				oTable.fnSettings().oLoadedState.yadcfState[table_selector_jq_friendly][column_number] =
					{
						'from' : "",
						'to' : ""
					};
			} else {
				yadcfState = {};
				yadcfState[table_selector_jq_friendly] = [];
				yadcfState[table_selector_jq_friendly][column_number] = {
					'from' : "",
					'to' : ""
				};
				oTable.fnSettings().oLoadedState.yadcfState = yadcfState;
			}
			oTable.fnSettings().oApi._fnSaveState(oTable.fnSettings());
		}
		resetIApiIndex();

		$(event.target).parent().find(".yadcf-filter-range").removeClass("inuse");

		return;
	}

	function rangeNumberSliderClear(table_selector_jq_friendly, event) {
		event = eventTargetFixUp(event);
		$.fn.dataTableExt.iApiIndex = oTablesIndex[table_selector_jq_friendly];
		var oTable = oTables[table_selector_jq_friendly],
			min_val,
			max_val,
			currentFilterValues,
			column_number;

		column_number = parseInt($(event.target).prev().find(".yadcf-filter-range-number-slider").attr("id").replace("yadcf-filter-" + table_selector_jq_friendly + "-slider-", ""), 10);

		min_val = +$($(event.target).parent().find(".yadcf-filter-range-number-slider-min-tip-hidden")).text();
		max_val = +$($(event.target).parent().find(".yadcf-filter-range-number-slider-max-tip-hidden")).text();

		currentFilterValues = exGetColumnFilterVal(oTable, column_number);
		if (+currentFilterValues.from === min_val && +currentFilterValues.to === max_val) {
			return;
		}

		$("#" + $(event.target).prev().find(".yadcf-filter-range-number-slider").attr("id")).slider("option", "yadcf-reset", true);
		$("#" + $(event.target).prev().find(".yadcf-filter-range-number-slider").attr("id")).slider("option", "values", [min_val, max_val]);

		$($(event.target).prev().find(".ui-slider-handle")[0]).attr("tabindex", -1).focus();

		$($(event.target).prev().find(".ui-slider-handle")[0]).removeClass("inuse");
		$($(event.target).prev().find(".ui-slider-handle")[1]).removeClass("inuse");
		$(event.target).prev().find(".ui-slider-range").removeClass("inuse");

		oTable.fnDraw();
		resetIApiIndex();

		return;
	}

	function dateKeyUP(table_selector_jq_friendly, date_format, event) {
		var oTable,
			date,
			dateId,
			column_number;

		event = eventTargetFixUp(event);

		dateId = event.target.id;
		date = document.getElementById(dateId).value;
		try {
			if (date.length === (date_format.length + 2)) {
				date = (date !== "") ? $.datepicker.parseDate(date_format, date) : date;
			}
		} catch (err1) {}

		if (((date instanceof Date) || date === "")) {

			$.fn.dataTableExt.iApiIndex = oTablesIndex[table_selector_jq_friendly];
			oTable = oTables[table_selector_jq_friendly];
			column_number = parseInt(dateId.replace("yadcf-filter-" + table_selector_jq_friendly + "-", ""), 10);

			if (date instanceof Date) {
				$("#" + dateId).addClass('inuse');
				oTable.fnFilter(document.getElementById(dateId).value, column_number);
			} else {
				$("#" + dateId).removeClass('inuse');
			}
			if ($.trim(event.target.value) === '' && $(event.target).hasClass('inuse')) {
				$('#' + event.target.id).removeClass('inuse');
				oTable.fnFilter('', column_number);
			}
			resetIApiIndex();
		} else if ($(event.target).hasClass('inuse')) {

			$.fn.dataTableExt.iApiIndex = oTablesIndex[table_selector_jq_friendly];
			oTable = oTables[table_selector_jq_friendly];
			column_number = parseInt(dateId.replace("yadcf-filter-" + table_selector_jq_friendly + "-", ""), 10);

			$("#" + dateId).removeClass('inuse');

			oTable.fnFilter('', column_number);
			resetIApiIndex();
		}
	}

	function rangeDateKeyUP(table_selector_jq_friendly, date_format, event) {
		event = eventTargetFixUp(event);
		$.fn.dataTableExt.iApiIndex = oTablesIndex[table_selector_jq_friendly];
		var oTable = oTables[table_selector_jq_friendly],
			min,
			max,
			fromId,
			toId,
			column_number,
			options,
			keyUp;

		column_number = parseInt($(event.target).attr("id").replace('-from-date-', '').replace('-to-date-', '').replace('yadcf-filter-' + table_selector_jq_friendly, ''), 10);
		options = getOptions(oTable.selector)[column_number];

		keyUp = function () {
			if (event.target.id.indexOf("-from-") !== -1) {
				fromId = event.target.id;
				toId = event.target.id.replace("-from-", "-to-");

				min = document.getElementById(fromId).value;
				max = document.getElementById(toId).value;
			} else {
				toId = event.target.id;
				fromId = event.target.id.replace("-to-", "-from-");

				max =   document.getElementById(toId).value;
				min = document.getElementById(fromId).value;
			}

			try {
				if (min.length === (date_format.length + 2)) {
					min = (min !== "") ? $.datepicker.parseDate(date_format, min) : min;
				}
			} catch (err1) {}
			try {
				if (max.length === (date_format.length + 2)) {
					max = (max !== "") ? $.datepicker.parseDate(date_format, max) : max;
				}
			} catch (err2) {}

			if (((max instanceof Date) && (min instanceof Date) && (max >= min)) || min === "" || max === "") {

				if (oTable.fnSettings().oFeatures.bServerSide !== true) {
					oTable.fnDraw();
				} else {
					oTable.fnFilter(document.getElementById(fromId).value + '-yadcf_delim-' + document.getElementById(toId).value, column_number);
				}

				if (min instanceof Date) {
					$("#" + fromId).addClass("inuse");
				} else {
					$("#" + fromId).removeClass("inuse");
				}
				if (max instanceof Date) {
					$("#" + toId).addClass("inuse");
				} else {
					$("#" + toId).removeClass("inuse");
				}

				if ($.trim(event.target.value) === "" && $(event.target).hasClass("inuse")) {
					$("#" + event.target.id).removeClass("inuse");
				}

			}
			resetIApiIndex();
		};

		if (options.filter_delay === undefined) {
			keyUp(table_selector_jq_friendly, event);
		} else {
			yadcfDelay(function () {
				keyUp(table_selector_jq_friendly, event);
			}, options.filter_delay);
		}
	}

	function rangeNumberKeyUP(table_selector_jq_friendly, event) {
		event = eventTargetFixUp(event);
		$.fn.dataTableExt.iApiIndex = oTablesIndex[table_selector_jq_friendly];
		var oTable = oTables[table_selector_jq_friendly],
			min,
			max,
			fromId,
			toId,
			yadcfState,
			column_number,
			options,
			keyUp;

		column_number = parseInt($(event.target).attr("id").replace('-from-', '').replace('-to-', '').replace('yadcf-filter-' + table_selector_jq_friendly, ''), 10);
		options = getOptions(oTable.selector)[column_number];

		keyUp = function () {

			if (event.target.id.indexOf("-from-") !== -1) {
				fromId = event.target.id;
				toId = event.target.id.replace("-from-", "-to-");

				min = document.getElementById(fromId).value;
				max = document.getElementById(toId).value;
			} else {
				toId = event.target.id;
				fromId = event.target.id.replace("-to-", "-from-");

				max =   document.getElementById(toId).value;
				min = document.getElementById(fromId).value;
			}

			min = (min !== "") ? (+min) : min;
			max = (max !== "") ? (+max) : max;

			if ((!isNaN(max) && !isNaN(min) && (max >= min)) || min === "" || max === "") {

				if (oTable.fnSettings().oFeatures.bServerSide !== true) {
					oTable.fnDraw();
				} else {
					oTable.fnFilter(min + '-yadcf_delim-' + max, column_number);
				}
				if (document.getElementById(fromId).value !== "") {
					$("#" + fromId).addClass("inuse");
				}
				if (document.getElementById(toId).value !== "") {
					$("#" + toId).addClass("inuse");
				}

				if ($.trim(event.target.value) === "" && $(event.target).hasClass("inuse")) {
					$("#" + event.target.id).removeClass("inuse");
				}
				if (!oTable.fnSettings().oLoadedState) {
					oTable.fnSettings().oLoadedState = {};
					oTable.fnSettings().oApi._fnSaveState(oTable.fnSettings());
				}
				if (oTable.fnSettings().oFeatures.bStateSave === true) {
					if (oTable.fnSettings().oLoadedState.yadcfState !== undefined && oTable.fnSettings().oLoadedState.yadcfState[table_selector_jq_friendly] !== undefined) {
						oTable.fnSettings().oLoadedState.yadcfState[table_selector_jq_friendly][column_number] =
							{
								'from' : min,
								'to' : max
							};
					} else {
						yadcfState = {};
						yadcfState[table_selector_jq_friendly] = [];
						yadcfState[table_selector_jq_friendly][column_number] = {
							'from' : min,
							'to' : max
						};
						oTable.fnSettings().oLoadedState.yadcfState = yadcfState;
					}
					oTable.fnSettings().oApi._fnSaveState(oTable.fnSettings());
				}
			}
			resetIApiIndex();
		};

		if (options.filter_delay === undefined) {
			keyUp();
		} else {
			yadcfDelay(function () {
				keyUp();
			}, options.filter_delay);
		}
	}

	function doFilterMultiTablesMultiSelect(tablesSelectors, event, column_number_str, clear) {

		var columnsObj = getOptions(tablesSelectors + '_' + column_number_str)[column_number_str],
			regex = false,
			smart = true,
			caseInsen = true,
			tablesAsOne,
			tablesArray = oTables[tablesSelectors],
			selected_values = $(event.target).val(),
			i;

		event = eventTargetFixUp(event);
		tablesAsOne = new $.fn.dataTable.Api(tablesArray);

		if (clear !== undefined || selected_values == undefined || selected_values.length === 0) {
			if (clear !== undefined) {
				$(event.target).parent().find('select').val('-1').focus();
				$(event.target).parent().find('selectn ').removeClass("inuse");
			}
			if (columnsObj.column_number instanceof Array) {
				tablesAsOne.columns(columnsObj.column_number).search('').draw();
			} else {
				tablesAsOne.search('').draw();
			}

			refreshSelectPlugin(columnsObj.select_type, $('#' + columnsObj.filter_container_id + ' select'), '-1');
			return;
		}

		$(event.target).addClass("inuse");

		regex = true;
		smart = false;
		caseInsen = columnsObj.case_insensitive;

		if (selected_values !== null) {
			for (i = selected_values.length - 1; i >= 0; i--) {
				if (selected_values[i] === "-1") {
					selected_values.splice(i, 1);
					break;
				}
			}
			if (selected_values.length !== 0) {
				selected_values = selected_values.join('narutouzomaki');
				selected_values = selected_values.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1");
				selected_values = selected_values.split('narutouzomaki').join('|');
			}
		}
		if (columnsObj.filter_match_mode === "exact") {
			selected_values = "^" + selected_values + "$";
		} else if (columnsObj.filter_match_mode === "startsWith") {
			selected_values = "^" + selected_values;
		}
		if (columnsObj.column_number instanceof Array) {
			tablesAsOne.columns(columnsObj.column_number).search(selected_values, regex, smart, caseInsen).draw();
		} else {
			tablesAsOne.search(selected_values, regex, smart, caseInsen).draw();
		}
	}

	function doFilterMultiTables(tablesSelectors, event, column_number_str, clear) {

		var columnsObj = getOptions(tablesSelectors + '_' + column_number_str)[column_number_str],
			regex = false,
			smart = true,
			caseInsen = true,
			serachVal,
			tablesAsOne,
			tablesArray = oTables[tablesSelectors];

		event = eventTargetFixUp(event);
		tablesAsOne = new $.fn.dataTable.Api(tablesArray);

		if (clear !== undefined || event.target.value === '-1') {
			if (clear !== undefined) {
				$(event.target).parent().find('select').val('-1').focus();
				$(event.target).parent().find('select').removeClass("inuse");
			}
			if (columnsObj.column_number instanceof Array) {
				tablesAsOne.columns(columnsObj.column_number).search('').draw();
			} else {
				tablesAsOne.search('').draw();
			}

			refreshSelectPlugin(columnsObj.select_type, $('#' + columnsObj.filter_container_id + ' select'), '-1');

			return;
		}

		$(event.target).addClass("inuse");

		serachVal = event.target.value;
		smart = false;
		caseInsen = columnsObj.case_insensitive;
/*
		if (columnsObj.filter_match_mode === "contains") {
			regex = false;
		} else if (columnsObj.filter_match_mode === "exact") {
			regex = true;
			serachVal = "^" + serachVal + "$";
		} else if (columnsObj.filter_match_mode === "startsWith") {
			regex = true;
			serachVal = "^" + serachVal;
		}*/
		if (columnsObj.column_number instanceof Array) {
			tablesAsOne.columns(columnsObj.column_number).search(serachVal, regex, smart, caseInsen).draw();
		} else {
			tablesAsOne.search(serachVal, regex, smart, caseInsen).draw();
		}
	}

	function textKeyUpMultiTables(tablesSelectors, event, column_number_str, clear) {

		var keyUp,
			columnsObj = getOptions(tablesSelectors + '_' + column_number_str)[column_number_str],
			regex = false,
			smart = true,
			caseInsen = true,
			serachVal,
			tablesAsOne,
			tablesArray = oTables[tablesSelectors];

		event = eventTargetFixUp(event);
		tablesAsOne = new $.fn.dataTable.Api(tablesArray);

		keyUp = function (tablesAsOne, event, clear) {

			if (clear !== undefined || event.target.value === '') {
				if (clear !== undefined) {
					$(event.target).prev().val("").focus();
					$(event.target).prev().removeClass("inuse");
				} else {
					$(event.target).val("").focus();
					$(event.target).removeClass("inuse");
				}
				if (columnsObj.column_number instanceof Array) {
					tablesAsOne.columns(columnsObj.column_number).search('').draw();
				} else {
					tablesAsOne.search('').draw();
				}
				return;
			}

			$(event.target).addClass("inuse");

			serachVal = event.target.value;
			smart = false;
			caseInsen = columnsObj.case_insensitive;
/*
			if (columnsObj.filter_match_mode === "contains") {
				regex = false;
			} else if (columnsObj.filter_match_mode === "exact") {
				regex = true;
				serachVal = "^" + serachVal + "$";
			} else if (columnsObj.filter_match_mode === "startsWith") {
				regex = true;
				serachVal = "^" + serachVal;
			}
*/
			if (columnsObj.column_number instanceof Array) {
				tablesAsOne.columns(columnsObj.column_number).search(serachVal, regex, smart, caseInsen).draw();
			} else {
				tablesAsOne.search(serachVal, regex, smart, caseInsen).draw();
			}

		};

		if (columnsObj.filter_delay === undefined) {
			keyUp(tablesAsOne, event, clear);
		} else {
			yadcfDelay(function () {
				keyUp(tablesAsOne, event, clear);
			}, columnsObj.filter_delay);
		}
	}

	function textKeyUP(table_selector_jq_friendly, column_number, clear) {
		var column_number_filter,
			oTable = oTables[table_selector_jq_friendly],
			keyUp,
			columnObj,
			settingsDt = getSettingsObjFromTable(oTable),
			exclude;

		column_number_filter = calcColumnNumberFilter(settingsDt, column_number, table_selector_jq_friendly);

		columnObj = getOptions(oTable.selector)[column_number];

		keyUp = function (table_selector_jq_friendly, column_number, clear) {
			$.fn.dataTableExt.iApiIndex = oTablesIndex[table_selector_jq_friendly];

			if (clear === 'clear' || $("#yadcf-filter-" + table_selector_jq_friendly + "-" + column_number).val() === '') {
				if (clear === 'clear' && exGetColumnFilterVal(oTable, column_number) === '') {
					return;
				}
				$("#yadcf-filter-" + table_selector_jq_friendly + "-" + column_number).val("").focus();
				$("#yadcf-filter-" + table_selector_jq_friendly + "-" + column_number).removeClass("inuse");
				oTable.fnFilter("", column_number_filter);
				resetIApiIndex();
				return;
			}

			if (columnObj.exclude === true) {
				exclude = $("#yadcf-filter-" + table_selector_jq_friendly + "-" + column_number).closest('.yadcf-filter-wrapper').find('.yadcf-exclude-wrapper :checkbox').prop('checked');
			}
			$("#yadcf-filter-" + table_selector_jq_friendly + "-" + column_number).addClass("inuse");

			yadcfMatchFilter(oTable, $("#yadcf-filter-" + table_selector_jq_friendly + "-" + column_number).val(), columnObj.filter_match_mode, column_number_filter, exclude);

			resetIApiIndex();
		};

		if (columnObj.filter_delay === undefined) {
			keyUp(table_selector_jq_friendly, column_number, clear);
		} else {
			yadcfDelay(function () {
				keyUp(table_selector_jq_friendly, column_number, clear);
			}, columnObj.filter_delay);
		}
	}

	function autocompleteKeyUP(table_selector_jq_friendly, event) {
		event = eventTargetFixUp(event);

		if (event.target.value === "" && event.keyCode === 8 && $(event.target).hasClass("inuse")) {
			$.fn.dataTableExt.iApiIndex = oTablesIndex[table_selector_jq_friendly];
			var oTable = oTables[table_selector_jq_friendly],
				column_number = parseInt($(event.target).attr("id").replace("yadcf-filter-" + table_selector_jq_friendly + "-", ""), 10);

			$("#yadcf-filter-" + table_selector_jq_friendly + "-" + column_number).removeClass("inuse");
			$(document).removeData("#yadcf-filter-" + table_selector_jq_friendly + "-" + column_number + "_val");
			oTable.fnFilter("", column_number);
			resetIApiIndex();
		}
	}

	function isDOMSource(tableVar) {
		var settingsDt;
		settingsDt = getSettingsObjFromTable(tableVar);
		if (settingsDt.sAjaxSource == undefined && settingsDt.ajax == undefined) {
			return true;
		}
		return false;
	}

	function scrollXYHandler(oTable, table_selector) {
		var $tmpSelector,
			filters_position = $(document).data(table_selector + "_filters_position"),
			table_selector_jq_friendly = yadcf.generateTableSelectorJQFriendly(table_selector);

		if (filters_position === 'thead') {
			filters_position = '.dataTables_scrollHead';
		} else {
			filters_position = '.dataTables_scrollFoot';
		}
		if (oTable.fnSettings().oScroll.sX !== '' || oTable.fnSettings().oScroll.sY !== '') {
			$tmpSelector = $(table_selector).closest('.dataTables_scroll').find(filters_position + ' table');
			$tmpSelector.addClass('yadcf-datatables-table-' + table_selector_jq_friendly);
		}
	}

	function firstFromObject(obj) {
		var key;
		for (key in obj) {
			if (obj.hasOwnProperty(key)) {
				return key;
			}
		}
	}

	function initAndBindTable(oTable, table_selector, index, pTableDT) {

		var table_selector_jq_friendly = yadcf.generateTableSelectorJQFriendly(table_selector),
			table_selector_tmp;
        oTables[table_selector_jq_friendly] = oTable;
		tablesDT[table_selector_jq_friendly] = pTableDT;
		oTablesIndex[table_selector_jq_friendly] = index;

		scrollXYHandler(oTable, table_selector);

        if (isDOMSource(oTable)) {
			table_selector_tmp = table_selector;
			if (table_selector.indexOf(":eq") !== -1) {
				table_selector_tmp = table_selector.substring(0, table_selector.lastIndexOf(":eq"));
			}
			appendFilters(oTable, getOptions(table_selector_tmp), table_selector);
			if (getOptions(table_selector_tmp)[firstFromObject(getOptions(table_selector_tmp))].cumulative_filtering === true) {
				//when filters should be populated only from visible rows (non filtered)
				$(document).off('search.dt', oTable.selector).on('search.dt', oTable.selector, function (e, settings, json) {
					var table_selector_tmp = oTable.selector;
					if (table_selector.indexOf(":eq") !== -1) {
						table_selector_tmp = table_selector.substring(0, table_selector.lastIndexOf(":eq"));
					}
					appendFilters(oTable, getOptions(table_selector_tmp), oTable.selector);
				});
			}
        } else {
			appendFilters(oTable, getOptions(table_selector), table_selector);
			if (yadcfVersionCheck('1.10')) {
				$(document).off('draw.dt', oTable.selector).on('draw.dt', oTable.selector, function (event, ui) {
					appendFilters(oTable, yadcf.getOptions(ui.oInstance.selector), ui.oInstance.selector);
				});
				$(document).off('xhr.dt', oTable.selector).on('xhr.dt', oTable.selector, function (e, settings, json) {
					var col_num,
						column_number_filter,
						table_selector_jq_friendly = generateTableSelectorJQFriendly(oTable.selector);
					if (settings.oSavedState !== null) {
						initColReorder2(settings, table_selector_jq_friendly);
					}
					for (col_num in yadcf.getOptions(settings.oInstance.selector)) {
						if (yadcf.getOptions(settings.oInstance.selector).hasOwnProperty(col_num)) {
							if (json['yadcf_data_' + col_num] !== undefined) {
								column_number_filter = col_num;
								if (settings.oSavedState !== null) {
									column_number_filter = plugins[table_selector_jq_friendly].ColReorder[col_num];
								}
								yadcf.getOptions(settings.oInstance.selector)[col_num].data = json['yadcf_data_' + column_number_filter];
							}
						}
					}
				});
				$(document).off('column-visibility.dt', oTable.selector).on('column-visibility.dt', oTable.selector, function (e, settings, col_num, state) {
					var obj = {};
					if (state === true) {
						if ((plugins[table_selector_jq_friendly] !== undefined && plugins[table_selector_jq_friendly].ColReorder !== undefined)) {
							col_num = plugins[table_selector_jq_friendly].ColReorder[col_num];
						} else if (settings.oSavedState != undefined && settings.oSavedState.ColReorder !== undefined) {
							col_num = settings.oSavedState.ColReorder[col_num];
						}
						obj[col_num] = yadcf.getOptions(settings.oInstance.selector)[col_num];
						obj[col_num].column_number = col_num;
						if (obj[col_num] !== undefined) {
							appendFilters(oTables[yadcf.generateTableSelectorJQFriendly(settings.oInstance.selector)],
								obj,
								settings.oInstance.selector);
						}
					}
				});
				$(document).off('destroy.dt', oTable.selector).on('destroy.dt', oTable.selector, function (event, ui) {
					removeFilters(oTable, yadcf.getOptions(ui.oInstance.selector), ui.oInstance.selector);
				});
			} else {
				$(document).off('draw', oTable.selector).on('draw', oTable.selector, function (event, ui) {
					appendFilters(oTable, yadcf.getOptions(ui.oInstance.selector), ui.oInstance.selector);
				});
				$(document).off('destroy', oTable.selector).on('destroy', oTable.selector, function (event, ui) {
					removeFilters(oTable, yadcf.getOptions(ui.oInstance.selector), ui.oInstance.selector);
				});
			}
        }
		//events that affects both DOM and Ajax
		if (yadcfVersionCheck('1.10')) {
			$(document).off('destroy.dt', oTable.selector).on('destroy.dt', oTable.selector, function (event, ui) {
				removeFilters(oTable, yadcf.getOptions(ui.oInstance.selector), ui.oInstance.selector);
			});
		} else {
			$(document).off('destroy', oTable.selector).on('destroy', oTable.selector, function (event, ui) {
				removeFilters(oTable, yadcf.getOptions(ui.oInstance.selector), ui.oInstance.selector);
			});
		}
		$(document).off('column-reorder.dt', oTable.selector).on('column-reorder.dt', oTable.selector, function (e, settings, json) {
			var table_selector_jq_friendly = generateTableSelectorJQFriendly(oTable.selector);
			initColReorderFromEvent(table_selector_jq_friendly);
		});

		if (oTable.fnSettings().oFeatures.bStateSave === true) {
			if (yadcfVersionCheck('1.10')) {
				$(oTable.selector).off('stateSaveParams.dt').on('stateSaveParams.dt', function (e, settings, data) {
					if (settings.oLoadedState && settings.oLoadedState.yadcfState !== undefined) {
						data.yadcfState = settings.oLoadedState.yadcfState;
					} else {
						data.naruto = 'kurama';
					}
				});
			} else {
				$(oTable.selector).off('stateSaveParams').on('stateSaveParams', function (e, settings, data) {
					if (settings.oLoadedState && settings.oLoadedState.yadcfState !== undefined) {
						data.yadcfState = settings.oLoadedState.yadcfState;
					} else {
						data.naruto = 'kurama';
					}
				});
			}
			//when using DOM source
			if (isDOMSource(oTable)) {
				//we need to make sure that the yadcf state will be saved after page reload
				oTable.fnSettings().oApi._fnSaveState(oTable.fnSettings());
				//redraw the table in order to apply the filters
				oTable.fnDraw(false);
			}
		}
	}

    $.fn.yadcf = function (options_arg, params) {

    var tmpParams,
			i = 0,
			selector;

		if (params === undefined) {
			params = {};
		}


		if (typeof params === 'string') {
			tmpParams = params;
			params = {};
			params.filters_position = tmpParams;
		}
		if (params.filters_position === undefined || params.filters_position === 'header') {
			params.filters_position = 'thead';
		} else {
			params.filters_position = 'tfoot';
		}
		$(document).data(this.selector + "_filters_position", params.filters_position);
    if ($(this.selector).length === 1) {
			setOptions(this.selector, options_arg, params);
			initAndBindTable(this, this.selector, 0);
			/*setOptions(this.selector, options_arg, params);
			initAndBindTable(this, this.selector, 0);*/
		} else {
			for (i; i < $(this.selector).length; i++) {
				$.fn.dataTableExt.iApiIndex = i;
				selector = this.selector + ":eq(" + i + ")";
				setOptions(this.selector, options_arg, params);
				initAndBindTable(this, selector, i);
			}
			$.fn.dataTableExt.iApiIndex = 0;
		}
        return this;
    };

	function init(oTable, options_arg, params) {
		var instance = oTable.settings()[0].oInstance,
			i = 0,
			selector,
			tmpParams;

		if (params === undefined) {
			params = {};
		}

		if (typeof params === 'string') {
			tmpParams = params;
			params = {};
			params.filters_position = tmpParams;
		}
		if (params.filters_position === undefined || params.filters_position === 'header') {
			params.filters_position = 'thead';
		} else {
			params.filters_position = 'tfoot';
		}
		$(document).data(instance.selector + "_filters_position", params.filters_position);

		if ($(instance.selector).length === 1) {
			setOptions(instance.selector, options_arg, params);
			initAndBindTable(instance, instance.selector, 0, oTable);
		} else {
			for (i; i < $(instance.selector).length; i++) {
				$.fn.dataTableExt.iApiIndex = i;
				selector = instance.selector + ":eq(" + i + ")";
				setOptions(instance.selector, options_arg, params);
				initAndBindTable(instance, selector, i, oTable);
			}
			$.fn.dataTableExt.iApiIndex = 0;
		}
	}

	function appendFiltersMultipleTables(tablesArray, tablesSelectors, colObjDummy) {
		var filter_selector_string = "#" + colObjDummy.filter_container_id,
			$filter_selector = $(filter_selector_string).find(".yadcf-filter"),
			table_selector_jq_friendly = yadcf.generateTableSelectorJQFriendlyNew(tablesSelectors),
			options_tmp,
			ii,
			column_number_str = columnsArrayToString(colObjDummy.column_number).column_number_str,
			tableTmp,
			tableTmpArr,
			tableTmpArrIndex,
			filterOptions = getOptions(tablesSelectors + '_' + column_number_str)[column_number_str],
			column_number_index,
			columnsTmpArr,
			settingsDt,
			tmpStr,
			columnForStateSaving;

		//add a wrapper to hold both filter and reset button
		$(filter_selector_string).append("<div id=\"yadcf-filter-wrapper-" + table_selector_jq_friendly + '-' + column_number_str + "\" class=\"yadcf-filter-wrapper\"></div>");
		filter_selector_string = filter_selector_string + " div.yadcf-filter-wrapper";
		if (column_number_str.indexOf('_') !== -1) {
			columnForStateSaving = column_number_str.split('_')[0];
		} else {
			columnForStateSaving = column_number_str;
		}

		switch (filterOptions.filter_type) {
		case 'text':
			$(filter_selector_string).append("<input type=\"text\" id=\"yadcf-filter-" + table_selector_jq_friendly + '-' + column_number_str + "\" class=\"yadcf-filter\" onmousedown=\"yadcf.stopPropagation(event);\" onclick='yadcf.stopPropagation(event);"
				+ "' placeholder='" + filterOptions.filter_default_label + "'" + " onkeyup=\"yadcf.textKeyUpMultiTables('" + tablesSelectors + "',event,'" + column_number_str + "');\"></input>");
			if (filterOptions.filter_reset_button_text !== false) {
				$(filter_selector_string).find(".yadcf-filter").after("<button type=\"button\" " + " id=\"yadcf-filter-" + table_selector_jq_friendly + '-' + column_number_str + "-reset\" onmousedown=\"yadcf.stopPropagation(event);\" " +
					"onclick=\"yadcf.stopPropagation(event);yadcf.textKeyUpMultiTables('" + tablesSelectors + "', event,'" + column_number_str + "','clear'); return false;\" class=\"yadcf-filter-reset-button\">" + filterOptions.filter_reset_button_text + "</button>");
			}
			if (tablesArray[0].table !== undefined) {
				tableTmp = $('#' + tablesArray[0].table().node().id).dataTable();
			} else {
				tableTmp = tablesArray[0];
			}
			settingsDt = getSettingsObjFromTable(tableTmp);
			if (settingsDt.aoPreSearchCols[columnForStateSaving].sSearch !== '') {
				tmpStr = settingsDt.aoPreSearchCols[columnForStateSaving].sSearch;
				tmpStr = yadcfParseMatchFilter(tmpStr, filterOptions.filter_match_mode);
				$('#yadcf-filter-' + table_selector_jq_friendly + '-' + column_number_str).val(tmpStr).addClass("inuse");
			}
			break;
		case 'select':
		case 'multi_select':
			if (filterOptions.select_type === undefined) {
				options_tmp = "<option data-placeholder=\"true\" value=\"" + "-1" + "\">" + filterOptions.filter_default_label + "</option>";
			} else {
				options_tmp = "";
			}
			if (filterOptions.select_type === 'select2' && filterOptions.select_type_options.placeholder !== undefined && filterOptions.select_type_options.allowClear === true) {
				options_tmp = "<option value=\"\"></option>";
			}
			if (filterOptions.data === undefined) {
				filterOptions.data = [];
				tableTmpArr = tablesSelectors.split(',');
				for (tableTmpArrIndex = 0; tableTmpArrIndex < tableTmpArr.length; tableTmpArrIndex++) {
					if (tablesArray[tableTmpArrIndex].table !== undefined) {
						tableTmp = $('#' + tablesArray[tableTmpArrIndex].table().node().id).dataTable();
					} else {
						tableTmp = tablesArray[tableTmpArrIndex];
					}
					if (isDOMSource(tableTmp)) {
						//check if ajax source, if so, listen for dt.draw
						columnsTmpArr = filterOptions.column_number;
						for (column_number_index = 0; column_number_index < columnsTmpArr.length; column_number_index++) {
							filterOptions.column_number = columnsTmpArr[column_number_index];
							filterOptions.data = filterOptions.data.concat(parseTableColumn(tableTmp, filterOptions, table_selector_jq_friendly));
						}
						filterOptions.column_number = columnsTmpArr;
					} else {
						$(document).off('draw.dt', '#' + tablesArray[tableTmpArrIndex].table().node().id).on('draw.dt', '#' + tablesArray[tableTmpArrIndex].table().node().id, function (event, ui) {
							var options_tmp = '',
								ii;
							columnsTmpArr = filterOptions.column_number;
							for (column_number_index = 0; column_number_index < columnsTmpArr.length; column_number_index++) {
								filterOptions.column_number = columnsTmpArr[column_number_index];
								filterOptions.data = filterOptions.data.concat(parseTableColumn(tableTmp, filterOptions, table_selector_jq_friendly));
							}
							filterOptions.column_number = columnsTmpArr;
							filterOptions.data = sortColumnData(filterOptions.data, filterOptions);
							for (ii = 0; ii < filterOptions.data.length; ii++) {
								options_tmp += "<option value=\"" + filterOptions.data[ii] + "\">" + filterOptions.data[ii] + "</option>";
							}
							$('#' + filterOptions.filter_container_id + ' select').empty().append(options_tmp);

							if (filterOptions.select_type !== undefined) {
								initializeSelectPlugin(filterOptions.select_type, $('#' + filterOptions.filter_container_id + ' select'), filterOptions.select_type_options);
							}
						});
					}
				}
			}

			filterOptions.data = sortColumnData(filterOptions.data, filterOptions);

			if (tablesArray[0].table !== undefined) {
				tableTmp = $('#' + tablesArray[0].table().node().id).dataTable();
			} else {
				tableTmp = tablesArray[0];
			}
			settingsDt = getSettingsObjFromTable(tableTmp);

			if (typeof filterOptions.data[0] === 'object') {
				for (ii = 0; ii < filterOptions.data.length; ii++) {
					options_tmp += "<option value=\"" + filterOptions.data[ii].value + "\">" + filterOptions.data[ii].label + "</option>";
				}
			} else {
				for (ii = 0; ii < filterOptions.data.length; ii++) {
					options_tmp += "<option value=\"" + filterOptions.data[ii] + "\">" + filterOptions.data[ii] + "</option>";
				}
			}
			if (filterOptions.filter_type === 'select') {
				$(filter_selector_string).append("<select id=\"yadcf-filter-" + table_selector_jq_friendly + '-' + column_number_str + "\" class=\"yadcf-filter\" " +
					"onchange=\"yadcf.doFilterMultiTables('" + tablesSelectors + "',event,'" + column_number_str + "')\" onmousedown=\"yadcf.stopPropagation(event);\" onclick='yadcf.stopPropagation(event);'>" + options_tmp + "</select>");
				if (settingsDt.aoPreSearchCols[columnForStateSaving].sSearch !== '') {
					tmpStr = settingsDt.aoPreSearchCols[columnForStateSaving].sSearch;
					tmpStr = yadcfParseMatchFilter(tmpStr, filterOptions.filter_match_mode);
					$('#yadcf-filter-' + table_selector_jq_friendly + '-' + column_number_str).val(tmpStr).addClass("inuse");
				}
			} else if (filterOptions.filter_type === 'multi_select') {
				$(filter_selector_string).append("<select multiple data-placeholder=\"" + filterOptions.filter_default_label + "\" id=\"yadcf-filter-" + table_selector_jq_friendly + '-' + column_number_str + "\" class=\"yadcf-filter\" " +
					"onchange=\"yadcf.doFilterMultiTablesMultiSelect('" + tablesSelectors + "',event,'" + column_number_str + "')\" onmousedown=\"yadcf.stopPropagation(event);\" onclick='yadcf.stopPropagation(event);'>" + options_tmp + "</select>");
				if (settingsDt.aoPreSearchCols[columnForStateSaving].sSearch !== '') {
					tmpStr = settingsDt.aoPreSearchCols[columnForStateSaving].sSearch;
					tmpStr = yadcfParseMatchFilterMultiSelect(tmpStr, filterOptions.filter_match_mode);
					tmpStr = tmpStr.replace(/\\/g, "");
					tmpStr = tmpStr.split("|");
					$('#yadcf-filter-' + table_selector_jq_friendly + '-' + column_number_str).val(tmpStr);
				}
			}
			if (filterOptions.filter_type === 'select') {
				if (filterOptions.filter_reset_button_text !== false) {
					$(filter_selector_string).find(".yadcf-filter").after("<button type=\"button\" " + " id=\"yadcf-filter-" + table_selector_jq_friendly  + '-' + column_number_str + "-reset\" onmousedown=\"yadcf.stopPropagation(event);\" " +
						"onclick=\"yadcf.stopPropagation(event);yadcf.doFilterMultiTables('" + tablesSelectors + "', event,'" + column_number_str + "','clear'); return false;\" class=\"yadcf-filter-reset-button\">" + filterOptions.filter_reset_button_text + "</button>");
				}
			} else if (filterOptions.filter_type === 'multi_select') {
				if (filterOptions.filter_reset_button_text !== false) {
					$(filter_selector_string).find(".yadcf-filter").after("<button type=\"button\" " + " id=\"yadcf-filter-" + table_selector_jq_friendly + '-' + column_number_str + "-reset\" onmousedown=\"yadcf.stopPropagation(event);\" " +
						"onclick=\"yadcf.stopPropagation(event);yadcf.doFilterMultiTablesMultiSelect('" + tablesSelectors + "', event,'" + column_number_str + "','clear'); return false;\" class=\"yadcf-filter-reset-button\">" + filterOptions.filter_reset_button_text + "</button>");
				}
			}

			if (filterOptions.select_type !== undefined) {
				initializeSelectPlugin(filterOptions.select_type, $("#yadcf-filter-" + table_selector_jq_friendly + '-' + column_number_str), filterOptions.select_type_options);
			}
			break;
		default:
			alert('Filters Multiple Tables does not support ' + filterOptions.filter_type);
		}
	}

	function initMultipleTables(tablesArray, filtersOptions) {
		var i,
			tablesSelectors = '',
			default_options = {
				filter_type : "text",
				filter_container_id: '',
				filter_reset_button_text: 'x',
				case_insensitive: true
			},
			columnsObjKey,
			columnsObj,
			columnsArrIndex,
			column_number_str,
			dummyArr;

		for (columnsArrIndex = 0; columnsArrIndex < filtersOptions.length; columnsArrIndex++) {
			dummyArr = [];
			columnsObj = filtersOptions[columnsArrIndex];
			if (columnsObj.filter_default_label === undefined) {
				if (columnsObj.filter_type === "select" || columnsObj.filter_type === 'custom_func') {
					columnsObj.filter_default_label = "Select value";
				} else if (columnsObj.filter_type === "multi_select" || columnsObj.filter_type === 'multi_select_custom_func') {
					columnsObj.filter_default_label = "Select values";
				} else if (columnsObj.filter_type === "auto_complete" || columnsObj.filter_type === "text") {
					columnsObj.filter_default_label = 'Type to filter';
				} else if (columnsObj.filter_type === "range_number" || columnsObj.filter_type === "range_date") {
					columnsObj.filter_default_label = ["from", "to"];
				} else if (columnsObj.filter_type === "date") {
					columnsObj.filter_default_label = "Select a date";
				}
			}
			columnsObj = $.extend({}, default_options, columnsObj);

			column_number_str = columnsArrayToString(columnsObj.column_number).column_number_str;
			columnsObj.column_number_str = column_number_str;

			dummyArr.push(columnsObj);
			tablesSelectors = '';
			for (i = 0; i < tablesArray.length; i++) {
				if (tablesArray[i].table !== undefined) {
					tablesSelectors += tablesArray[i].table().node().id + ',';
				} else {
					tablesSelectors += getSettingsObjFromTable(tablesArray[i]).sTableId;
				}
			}
			tablesSelectors = tablesSelectors.substring(0, tablesSelectors.length - 1);

			setOptions(tablesSelectors + '_' + column_number_str, dummyArr);
			oTables[tablesSelectors] = tablesArray;
			appendFiltersMultipleTables(tablesArray, tablesSelectors, columnsObj);
		}
	}

	function initMultipleColumns(table, filtersOptions) {
		var tablesArray = [];
		tablesArray.push(table);
		initMultipleTables(tablesArray, filtersOptions);
	}

    function stopPropagation(evt) {
		if (evt.stopPropagation !== undefined) {
			evt.stopPropagation();
		} else {
			evt.cancelBubble = true;
		}
	}

	//--------------------------------------------------------
	function exInternalFilterColumnAJAXQueue(table_arg, col_filter_arr) {
		return function () {
			exFilterColumn(table_arg, col_filter_arr, true);
		};
	}

	function exFilterColumn(table_arg, col_filter_arr, ajaxSource) {
		var table_selector_jq_friendly,
			j,
			tmpStr,
			column_number,
			column_position,
			filter_value,
			fromId,
			toId,
			sliderId,
			optionsObj,
			min,
			max;
		//check if the table arg is from new datatables API (capital "D")
		if (table_arg.settings !== undefined) {
			table_arg = table_arg.settings()[0].oInstance;
		}
		table_selector_jq_friendly = yadcf.generateTableSelectorJQFriendly(table_arg.selector);
		if (isDOMSource(table_arg) || ajaxSource === true) {
			for (j = 0; j < col_filter_arr.length; j++) {
				column_number = col_filter_arr[j][0];
				column_position = column_number;
				if (plugins[table_selector_jq_friendly] !== undefined && (plugins[table_selector_jq_friendly] !== undefined && plugins[table_selector_jq_friendly].ColReorder !== undefined)) {
					column_position = plugins[table_selector_jq_friendly].ColReorder[column_number];
				}
				optionsObj = getOptions(table_arg.selector)[column_number];
				filter_value = col_filter_arr[j][1];

				switch (optionsObj.filter_type) {
				case 'auto_complete':
				case 'text':
				case 'date':
					$('#yadcf-filter-' + table_selector_jq_friendly + '-' + column_number).val(filter_value).addClass('inuse');
					tmpStr = yadcfMatchFilterString(table_arg, column_position, filter_value, optionsObj.filter_match_mode, false);
					table_arg.fnSettings().aoPreSearchCols[column_position].sSearch = tmpStr;
					break;
				case 'select':
					$('#yadcf-filter-' + table_selector_jq_friendly + '-' + column_number).val(filter_value).addClass('inuse');
					tmpStr = yadcfMatchFilterString(table_arg, column_position, filter_value, optionsObj.filter_match_mode, false);
					table_arg.fnSettings().aoPreSearchCols[column_position].sSearch = tmpStr;
					if (optionsObj.select_type !== undefined) {
						refreshSelectPlugin(optionsObj.select_type, $('#yadcf-filter-' + table_selector_jq_friendly + '-' + column_number), '-1');
					}
					break;
				case 'multi_select':
					$('#yadcf-filter-' + table_selector_jq_friendly + '-' + column_number).val(filter_value);
					tmpStr = yadcfMatchFilterString(table_arg, column_position, filter_value, optionsObj.filter_match_mode, true);
					table_arg.fnSettings().aoPreSearchCols[column_position].sSearch = tmpStr;
					if (optionsObj.select_type !== undefined) {
						refreshSelectPlugin(optionsObj.select_type, $('#yadcf-filter-' + table_selector_jq_friendly + '-' + column_number), '-1');
					}
					break;
				case 'range_date':
					fromId = 'yadcf-filter-' + table_selector_jq_friendly + '-from-date-' + column_number;
					toId = 'yadcf-filter-' + table_selector_jq_friendly + '-to-date-' + column_number;
					if (filter_value.from !== '') {
						$('#' + fromId).val(filter_value.from);
						$('#' + fromId).addClass('inuse');
					}
					if (filter_value.to !== '') {
						$('#' + toId).val(filter_value.to);
						$('#' + toId).addClass('inuse');
					}
					if (table_arg.fnSettings().oFeatures.bServerSide === true) {
						min = filter_value.from;
						max = filter_value.to;
						table_arg.fnSettings().aoPreSearchCols[column_position].sSearch = min + '-yadcf_delim-' + max;
					}
					saveStateSave(table_arg, column_number, table_selector_jq_friendly, filter_value.from, filter_value.to);
					break;
				case 'range_number':
					fromId = 'yadcf-filter-' + table_selector_jq_friendly + '-from-' + column_number;
					toId = 'yadcf-filter-' + table_selector_jq_friendly + '-to-' + column_number;
					if (filter_value.from !== '') {
						$('#' + fromId).val(filter_value.from);
						$('#' + fromId).addClass('inuse');
					}
					if (filter_value.to !== '') {
						$('#' + toId).val(filter_value.to);
						$('#' + toId).addClass('inuse');
					}
					if (table_arg.fnSettings().oFeatures.bServerSide === true) {
						table_arg.fnSettings().aoPreSearchCols[column_position].sSearch = filter_value.from + '-yadcf_delim-' + filter_value.to;
					}
					saveStateSave(table_arg, column_number, table_selector_jq_friendly, filter_value.from, filter_value.to);
					break;
				case 'range_number_slider':
					sliderId = 'yadcf-filter-' + table_selector_jq_friendly + '-slider-' + column_number;
					fromId = 'yadcf-filter-' + table_selector_jq_friendly + '-min_tip-' + column_number;
					toId = 'yadcf-filter-' + table_selector_jq_friendly + '-max_tip-' + column_number;
					if (filter_value.from !== '') {
						min = $('#' + fromId).closest('.yadcf-filter-range-number-slider').find(".yadcf-filter-range-number-slider-min-tip-hidden").text();
						max = $('#' + fromId).closest('.yadcf-filter-range-number-slider').find(".yadcf-filter-range-number-slider-max-tip-hidden").text();
						$('#' + fromId).text(filter_value.from);
						if (min !== filter_value.from) {
							$('#' + fromId).parent().addClass('inuse');
							$('#' + fromId).parent().parent().find('ui-slider-range').addClass('inuse');
						}
						$('#' + sliderId).slider('values', 0, filter_value.from);
					}
					if (filter_value.to !== '') {
						$('#' + toId).text(filter_value.to);
						if (max !== filter_value.to) {
							$('#' + toId).parent().addClass('inuse');
							$('#' + toId).parent().parent().find('.ui-slider-range').addClass('inuse');
						}
						$('#' + sliderId).slider('values', 1, filter_value.to);
					}
					if (table_arg.fnSettings().oFeatures.bServerSide === true) {
						table_arg.fnSettings().aoPreSearchCols[column_position].sSearch = filter_value.from + '-yadcf_delim-' + filter_value.to;
					}
					saveStateSave(table_arg, column_number, table_selector_jq_friendly, filter_value.from, filter_value.to);
					break;
				case 'custom_func':
				case 'multi_select_custom_func':
					$('#yadcf-filter-' + table_selector_jq_friendly + '-' + column_number).val(filter_value).addClass('inuse');
					if (table_arg.fnSettings().oFeatures.bServerSide === true) {
						table_arg.fnSettings().aoPreSearchCols[column_position].sSearch = filter_value;
					}
					if (optionsObj.select_type !== undefined) {
						refreshSelectPlugin(optionsObj.select_type, $('#yadcf-filter-' + table_selector_jq_friendly + '-' + column_number), filter_value);
					}
					saveStateSave(table_arg, column_number, table_selector_jq_friendly, filter_value, '');
					break;
				}
			}
			if (table_arg.fnSettings().oFeatures.bServerSide !== true) {
				table_arg.fnDraw();
			} else {
				setTimeout(function () {
					table_arg.fnDraw();
				}, 10);
			}
        } else {
			exFilterColumnQueue.push(exInternalFilterColumnAJAXQueue(table_arg, col_filter_arr));
        }
	}

	function exGetColumnFilterVal(table_arg, column_number) {
		var retVal,
			fromId,
			toId,
			table_selector_jq_friendly,
			optionsObj;

		//check if the table arg is from new datatables API (capital "D")
		if (table_arg.settings !== undefined) {
			table_arg = table_arg.settings()[0].oInstance;
		}

		optionsObj = getOptions(table_arg.selector)[column_number];
		table_selector_jq_friendly = yadcf.generateTableSelectorJQFriendly(table_arg.selector);

		switch (optionsObj.filter_type) {
		case 'select':
		case 'custom_func':
			retVal = $('#yadcf-filter-' + table_selector_jq_friendly + '-' + column_number).val();
			if (retVal === '-1') {
				retVal = '';
			}
			break;
		case 'auto_complete':
		case 'text':
		case 'date':
			retVal = $('#yadcf-filter-' + table_selector_jq_friendly + '-' + column_number).val();
			break;
		case 'multi_select':
			retVal = $('#yadcf-filter-' + table_selector_jq_friendly + '-' + column_number).val();
			if (retVal === null) {
				retVal = '';
			}
			break;
		case 'range_date':
			retVal = {};
			fromId = 'yadcf-filter-' + table_selector_jq_friendly + '-from-date-' + column_number;
			toId = 'yadcf-filter-' + table_selector_jq_friendly + '-to-date-' + column_number;

			retVal.from = $('#' + fromId).val();
			retVal.to = $('#' + toId).val();
			break;
		case 'range_number':
			retVal = {};
			fromId = 'yadcf-filter-' + table_selector_jq_friendly + '-from-' + column_number;
			toId = 'yadcf-filter-' + table_selector_jq_friendly + '-to-' + column_number;

			retVal.from = $('#' + fromId).val();
			retVal.to = $('#' + toId).val();
			break;
		case 'range_number_slider':
			retVal = {};
			fromId = 'yadcf-filter-' + table_selector_jq_friendly + '-min_tip-' + column_number;
			toId = 'yadcf-filter-' + table_selector_jq_friendly + '-max_tip-' + column_number;

			retVal.from = $('#' + fromId).text();
			retVal.to = $('#' + toId).text();

			break;
		default:
			console.log('exGetColumnFilterVal error: no such filter_type: ' + optionsObj.filter_type);
		}
		return retVal;
	}

	function clearStateSave(oTable, column_number, table_selector_jq_friendly) {
		var yadcfState;
		if (oTable.fnSettings().oFeatures.bStateSave === true) {
			if (!oTable.fnSettings().oLoadedState) {
				oTable.fnSettings().oLoadedState = {};
				oTable.fnSettings().oApi._fnSaveState(oTable.fnSettings());
			}
			if (oTable.fnSettings().oLoadedState.yadcfState !== undefined && oTable.fnSettings().oLoadedState.yadcfState[table_selector_jq_friendly] !== undefined) {
				oTable.fnSettings().oLoadedState.yadcfState[table_selector_jq_friendly][column_number] = undefined;
			} else {
				yadcfState = {};
				yadcfState[table_selector_jq_friendly] = [];
				yadcfState[table_selector_jq_friendly][column_number] = undefined;
				oTable.fnSettings().oLoadedState.yadcfState = yadcfState;
			}
			oTable.fnSettings().oApi._fnSaveState(oTable.fnSettings());
		}
	}

	function saveStateSave(oTable, column_number, table_selector_jq_friendly, from, to) {
		var yadcfState;
		if (oTable.fnSettings().oFeatures.bStateSave === true) {
			if (!oTable.fnSettings().oLoadedState) {
				oTable.fnSettings().oLoadedState = {};
			}
			if (oTable.fnSettings().oLoadedState.yadcfState !== undefined && oTable.fnSettings().oLoadedState.yadcfState[table_selector_jq_friendly] !== undefined) {
				oTable.fnSettings().oLoadedState.yadcfState[table_selector_jq_friendly][column_number] = {
					'from' : from,
					'to' : to
				};
			} else {
				yadcfState = {};
				yadcfState[table_selector_jq_friendly] = [];
				yadcfState[table_selector_jq_friendly][column_number] = {
					'from' : from,
					'to' : to
				};
				oTable.fnSettings().oLoadedState.yadcfState = yadcfState;
			}
			oTable.fnSettings().oApi._fnSaveState(oTable.fnSettings());
		}
	}

	function exResetAllFilters(table_arg, noRedraw, columns) {
		var table_selector_jq_friendly,
			column_number,
			fromId,
			toId,
			sliderId,
			tableOptions,
			optionsObj,
			columnObjKey,
			settingsDt = getSettingsObjFromTable(table_arg),
			i;

		//check if the table arg is from new datatables API (capital "D")
		if (table_arg.settings !== undefined) {
			table_arg = table_arg.settings()[0].oInstance;
		}
		tableOptions = getOptions(table_arg.selector);
		table_selector_jq_friendly = yadcf.generateTableSelectorJQFriendly(table_arg.selector);
		settingsDt = getSettingsObjFromTable(table_arg);

		for (columnObjKey in tableOptions) {
			if (tableOptions.hasOwnProperty(columnObjKey)) {
				optionsObj = tableOptions[columnObjKey];
				column_number = optionsObj.column_number;

				if (columns !== undefined && $.inArray(column_number, columns) === -1) {
					continue;
				}
				$(document).removeData("#yadcf-filter-" + table_selector_jq_friendly + "-" + column_number + "_val");

				switch (optionsObj.filter_type) {
				case 'select':
				case 'custom_func':
					$('#yadcf-filter-' + table_selector_jq_friendly + '-' + column_number).val('-1').removeClass('inuse');
					table_arg.fnSettings().aoPreSearchCols[column_number].sSearch = '';
					if (optionsObj.select_type !== undefined) {
						refreshSelectPlugin(optionsObj.select_type, $('#yadcf-filter-' + table_selector_jq_friendly + '-' + column_number), '-1');
					}
					break;
				case 'auto_complete':
				case 'text':
				case 'date':
					$('#yadcf-filter-' + table_selector_jq_friendly + '-' + column_number).val('').removeClass('inuse');
					table_arg.fnSettings().aoPreSearchCols[column_number].sSearch = '';
					break;
				case 'multi_select':
				case 'multi_select_custom_func':
					$('#yadcf-filter-' + table_selector_jq_friendly + '-' + column_number).val('-1');
					$(document).data("#yadcf-filter-" + table_selector_jq_friendly + "-" + column_number + "_val", undefined);
					table_arg.fnSettings().aoPreSearchCols[column_number].sSearch = '';
					if (optionsObj.select_type !== undefined) {
						refreshSelectPlugin(optionsObj.select_type, $('#yadcf-filter-' + table_selector_jq_friendly + '-' + column_number), '-1');
					}
					break;
				case 'range_date':
					fromId = 'yadcf-filter-' + table_selector_jq_friendly + '-from-date-' + column_number;
					toId = 'yadcf-filter-' + table_selector_jq_friendly + '-to-date-' + column_number;
					$('#' + fromId).val('');
					$('#' + fromId).removeClass('inuse');
					$('#' + toId).val('');
					$('#' + toId).removeClass('inuse');
					if (table_arg.fnSettings().oFeatures.bServerSide === true) {
						table_arg.fnSettings().aoPreSearchCols[column_number].sSearch = '';
					}
					clearStateSave(table_arg, column_number, table_selector_jq_friendly);
					break;
				case 'range_number':
					fromId = 'yadcf-filter-' + table_selector_jq_friendly + '-from-' + column_number;
					toId = 'yadcf-filter-' + table_selector_jq_friendly + '-to-' + column_number;
					$('#' + fromId).val('');
					$('#' + fromId).removeClass('inuse');
					$('#' + toId).val('');
					$('#' + toId).removeClass('inuse');
					if (table_arg.fnSettings().oFeatures.bServerSide === true) {
						table_arg.fnSettings().aoPreSearchCols[column_number].sSearch = '';
					}
					clearStateSave(table_arg, column_number, table_selector_jq_friendly);
					break;
				case 'range_number_slider':
					sliderId = 'yadcf-filter-' + table_selector_jq_friendly + '-slider-' + column_number;
					fromId = 'yadcf-filter-' + table_selector_jq_friendly + '-min_tip-' + column_number;
					toId = 'yadcf-filter-' + table_selector_jq_friendly + '-max_tip-' + column_number;
					$('#' + fromId).text('');
					$('#' + fromId).parent().removeClass('inuse');
					$('#' + fromId).parent().parent().find('ui-slider-range').removeClass('inuse');
					$('#' + toId).text('');
					$('#' + toId).parent().removeClass('inuse');
					$('#' + toId).parent().parent().find('.ui-slider-range').removeClass('inuse');
					$('#' + sliderId).slider("option", "values", [$('#' + fromId).parent().parent().find('.yadcf-filter-range-number-slider-min-tip-hidden').text(), $('#' + fromId).parent().parent().find('.yadcf-filter-range-number-slider-max-tip-hidden').text()]);
					if (table_arg.fnSettings().oFeatures.bServerSide === true) {
						table_arg.fnSettings().aoPreSearchCols[column_number].sSearch = '';
					}
					clearStateSave(table_arg, column_number, table_selector_jq_friendly);
					break;
				}

			}
		}
		if (noRedraw !== true) {
			//clear global filter
			settingsDt.oPreviousSearch.sSearch = '';
			if (settingsDt.aanFeatures.f !== undefined) {
				for (i = 0; i < settingsDt.aanFeatures.f.length; i++) {
					$('input', settingsDt.aanFeatures.f[i]).val('');
				}
			}
			//end of clear global filter
			table_arg.fnDraw(settingsDt);
		}
	}

	function exResetFilters(table_arg, columns) {
		exResetAllFilters(table_arg, false, columns);
	}

	function exFilterExternallyTriggered(table_arg) {
		var columnsObj,
			columnObjKey,
			columnObj,
			filterValue,
			filtersValuesSingleElem,
			filtersValuesArr = [];

		//check if the table arg is from new datatables API (capital "D")
		if (table_arg.settings !== undefined) {
			table_arg = table_arg.settings()[0].oInstance;
		}
		columnsObj = getOptions(table_arg.selector);

		for (columnObjKey in columnsObj) {
			if (columnsObj.hasOwnProperty(columnObjKey)) {
				columnObj = columnsObj[columnObjKey];
				filterValue = exGetColumnFilterVal(table_arg, columnObj.column_number);
				if ((typeof filterValue === 'string' && filterValue !== '') || (typeof filterValue === 'object' && (filterValue.from !== '' || filterValue.to !== ''))) {
					filtersValuesSingleElem = [];
					filtersValuesSingleElem.push(columnObj.column_number);
					filtersValuesSingleElem.push(filterValue);
					filtersValuesArr.push(filtersValuesSingleElem);
				}
			}
		}
		exFilterColumn(table_arg, filtersValuesArr, true);
	}

    return {
		init : init,
		doFilter : doFilter,
		doFilterMultiSelect : doFilterMultiSelect,
		doFilterAutocomplete : doFilterAutocomplete,
		autocompleteKeyUP : autocompleteKeyUP,
		getOptions : getOptions,
		rangeNumberKeyUP : rangeNumberKeyUP,
		rangeDateKeyUP : rangeDateKeyUP,
		rangeClear : rangeClear,
		rangeNumberSliderClear : rangeNumberSliderClear,
		stopPropagation : stopPropagation,
		generateTableSelectorJQFriendly : generateTableSelectorJQFriendly,
		exFilterColumn : exFilterColumn,
		exGetColumnFilterVal : exGetColumnFilterVal,
		exResetAllFilters: exResetAllFilters,
		dateKeyUP : dateKeyUP,
		dateSelectSingle : dateSelectSingle,
		textKeyUP : textKeyUP,
		doFilterCustomDateFunc : doFilterCustomDateFunc,
		eventTargetFixUp : eventTargetFixUp,
		initMultipleTables: initMultipleTables,
		initMultipleColumns: initMultipleColumns,
		textKeyUpMultiTables: textKeyUpMultiTables,
		doFilterMultiTables: doFilterMultiTables,
		doFilterMultiTablesMultiSelect: doFilterMultiTablesMultiSelect,
		generateTableSelectorJQFriendlyNew: generateTableSelectorJQFriendlyNew,
		exFilterExternallyTriggered: exFilterExternallyTriggered,
		exResetFilters: exResetFilters,
		initSelectPluginCustomTriggers: initSelectPluginCustomTriggers
    };

}(jQuery));