Explorar el Código

TableAjax fix render Head, fix filtersClean

Piotr Labudda hace 10 años
padre
commit
6c96dd4bff
Se han modificado 1 ficheros con 288 adiciones y 261 borrados
  1. 288 261
      SE/se-lib/TableAjax.php

+ 288 - 261
SE/se-lib/TableAjax.php

@@ -642,6 +642,8 @@ class TableAjax extends ViewAjax {
 		priv.initialRender = function () {
 			_uiNode$Table = $('<table class="AjaxTable table table-striped table-hover table-bordered table-condensed"></table>').appendTo(_uiNodeCont);
 				_head = $('<thead></thead>').prependTo(_uiNode$Table);
+					_headSort = $('<tr class="sort"></tr>').prependTo(_head);
+					_headFilter = $('<tr class="filter"></tr>').appendTo(_head);
 				_body = $('<tbody></tbody>').insertAfter(_head);
 			$('<tfoot></tfoot>').insertAfter(_body);
 			_foot = $('<div class="foot tblAjax__footer"></div>').insertAfter(_uiNodeCont);
@@ -655,7 +657,8 @@ class TableAjax extends ViewAjax {
 			_mapEditorWrap = $('<div class="mapEditor" style="display:none"></div>').insertAfter(_foot);
 				_mapEditor = $('<div class="mapEditor-map"></div>').appendTo(_mapEditorWrap);
 			_popoverCell = $('<div class="popoverCell" style="display:none"></div>').insertAfter(_foot);
-			_foot = _head = _body = undefined;// TODO: refactor
+			_foot = _head = _body = _headSort = _headFilter = undefined;// TODO: refactor
+			/// console.log('L.<?php echo __LINE__; ?> priv.initialRender, _uiNode$Table: ', _uiNode$Table.html())
 		}
 
 		/*
@@ -669,274 +672,26 @@ class TableAjax extends ViewAjax {
 /// console.log('renderTable:: _uiNode$Table', _uiNode$Table);//TODO:DBG:RMME
 
 			//create the header which will later hold both sorting and filtering
-/// console.log('renderTable:: _head', _head);//TODO:DBG:RMME
+			/// console.log('L.<?php echo __LINE__; ?> renderTable:: _head', _head);//TODO:DBG:RMME
 			if (!_head) {
 				_headSort = _headFilter = _headSpecialFilter = undefined;
-				_head = $('<thead></thead>');
-				_uiNode$Table.find('thead').replaceWith(_head);
+				//_head = $('<thead></thead>');
+				//	$('<tr class="sort"></tr>').prependTo(_head);
+				//_uiNode$Table.find('thead').replaceWith(_head);
+				_head = _uiNode$Table.find('thead');
 			}
 
 			//create the header sorting row
 			if (!_headSort) {
-				_head.find('.sort i').tooltip('hide');
-				_head.find('.sort').remove();
-				_headSort = $('<tr class="sort"></tr>').prependTo(_head);
-
-				//create the functions column
-				if (priv.options.rowFunctions || priv.options.filtersClean) {
-					var headCell = $('<th class="text-right head-info stickyCol1"></th>').appendTo(_headSort);
-					$.map(priv.options.tblFunctions, function(funObj, funName){
-						var funHtml = $('<a></a>');
-						funHtml.attr('href', funObj.href || '#');
-						if (funObj.title) funHtml.attr('title', funObj.title);
-						if (funObj.icon) funHtml.html('<span class="glyphicon glyphicon-' + funObj.icon + '"></span> ');
-						if (funObj.method && priv[funObj.method] && typeof priv[funObj.method] == 'function') {
-							funHtml.on('click', priv[funObj.method]);
-						}
-						funHtml.appendTo(headCell);
-					});
-				}
-
-				//create the checkall toggle
-				if (_state.uniqueCol && priv.options.checkboxes) {
-					var checked = _checkToggleChecked ? 'checked' : '';
-					var headCell = $('<th></th>').appendTo(_headSort);
-					var elem = $('<input {0} class="checkToggle" type="checkbox" />'.f(checked)).appendTo(headCell);
-					elem.on('change', priv.checkToggleChanged);
-				}
-
-				//create the sortable headers
-				for (var i = 0; i < _state.colsSorted.length; i++) {
-					var column = _state.colsSorted[i];
-					var props = _data.cols[column];
-					if (!props.hidden) {
-						var headCell = $('<th class="ta-ordering"></th>').appendTo(_headSort);
-						if (i == 1) headCell.addClass('stickyCol2');
-
-						if (false) {// TODO: old way
-							var link = $('<a class="pull-left" href="#">{0}</a>'.f(props.friendly || column));
-							link.on('click', {column: column}, priv.columnClicked).appendTo(headCell);
-
-							if (props.tooltip) {
-								$('<i class="glyphicon glyphicon-info-sign"></i>').tooltip({
-									title: props.tooltip.trim(),
-									html: true,
-									container: 'body',
-									placement: "top",
-									delay: {
-										show: 500,
-										hide: 100
-									}
-								}).appendTo(link);
-							}
-
-							//Add sort arrow
-							if (column == _currSortCol) {
-								if (_currSortFlip) $('<i class="glyphicon glyphicon-chevron-down pull-right"></i>').appendTo(headCell);
-								else $('<i class="glyphicon glyphicon-chevron-up pull-right"></i>').appendTo(headCell);
-							}
-
-							//Add hide btn
-							if (column != 'ID') {
-								var hideColBtn = $('<i class="glyphicon glyphicon-remove pull-right hover-show"></i>');
-								hideColBtn.on('click', {column: column},  priv.columnHideClicked);
-								hideColBtn.appendTo(headCell);
-							}
-						}
-
-						if (props.type != 'special' && props.type != 'geom') {
-							headCell.on('click', {column: column}, priv.columnClicked);
-						}
-						var colTitle = column;
-						if (props.description && props.description.length > 0) {
-							colTitle = props.description;
-							colTitle += ' (' + column + ')';
-						}
-						else if (props._tsRetId > 0) {
-							colTitle = 'Kliknij na pole i przejdź do powiązanych rekordów (' + colTitle + ')';
-						}
-
-						if (props.friendly) {
-							var headCnt = $('<span class="pull-left" title="{1}">{0}</span>'.f(props.friendly, colTitle));
-						} else {
-							var headCnt = $('<span class="pull-left" title="{1}">{0}</span>'.f(column, colTitle));
-						}
-						headCnt.appendTo(headCell);
-
-						//Add sort arrow
-						if (column == _currSortCol) {
-							if (_currSortFlip) headCell.addClass('ta-ordering-down');
-							else headCell.addClass('ta-ordering-up');
-						}
-
-						if (column != 'ID') {
-							var hideColBtn = $('<i class="glyphicon glyphicon-remove remove-cell"></i>');
-							hideColBtn.on('click', {column: column},  priv.columnHideClicked);
-							hideColBtn.appendTo(headCell);
-						}
-
-					}
-				}
+				/// console.log('L.<?php echo __LINE__; ?> renderTable::renderTableTheadSort...');//TODO:DBG:RMME
+				priv.renderTableTheadSort();
 			}
 
 			//create the header filtering row
 			if (!_headFilter && priv.options.filter) {
-				_head.find(".filter").remove();
-				_headFilter = $('<tr class="filter"></tr>').appendTo(_head);
-				var headCell;
-				var elem;
-				var placeHolder = '';
-				var tooltip = '';
-
-				//create the functions column
-				if (priv.options.rowFunctions || priv.options.filtersClean) {
-					var headCell = $('<th class="text-right stickyCol1"></th>').appendTo(_headFilter);
-					if (priv.options.filtersClean) {
-						var elem = $('<button title="Kasuj filtry" class="btn btn-xs btn-link glyphicon glyphicon-remove"></button>').appendTo(headCell);
-						elem.on('click', priv.filtersClean);
-					}
-				}
-
-				//create the filter checkbox
-				if (_state.uniqueCol && priv.options.checkboxes) {
-					tooltip = priv.options.types.bool.filterTooltip || 'Toggle between:<br/>indeterminate,<br/>checked,<br/>unchecked';
-					headCell = $('<th></th>').appendTo(_headFilter);
-					elem = $('<input class="filter indeterminate" checked type="checkbox" />').appendTo(headCell);
-					$.map(_filterCols, function (colProps, col) {
-						if (col == "unique") {
-							if (colProps.filter) elem.prop('checked', true).removeClass('indeterminate');
-							else if (!colProps.filter) elem.prop('checked', false).removeClass('indeterminate');
-							else if (colProps.filter == '') elem.addClass('indeterminate');
-						}
-					});
-
-					if (tooltip) {
-						elem.tooltip({
-							title: tooltip.trim(),
-							html: true,
-							container: 'body',
-							trigger: 'hover',
-							placement: 'top',
-							delay: {
-								show: 500,
-								hide: 100
-							}
-						});
-					}
-					elem.on('click', {column: "unique"}, priv.filterChanged);
-				}
-
-				//create the column filters
-				for (var i = 0; i < _state.colsSorted.length; i++) {
-					var column = _state.colsSorted[i];
-					var props = _data.cols[column];
-					tooltip = props.filterTooltip === true ? undefined : props.filterTooltip === false ? '' : props.filterTooltip;
-					placeHolder = props.placeHolder === true ? undefined : props.placeHolder === false ? '' : props.placeHolder;
-
-					if (!props.hidden) {
-						headCell = $('<th></th>').appendTo(_headFilter);
-						if (i == 1) headCell.addClass('stickyCol2');
-
-						// @mark MarkTableAjaxFilterColType
-						switch (props.type || 'string') {
-								case "number":
-										if (placeHolder == undefined) placeHolder = priv.options.types.number.placeHolder;
-										placeHolder = (placeHolder === true || placeHolder == undefined) ? '10..20 =50' : placeHolder === false ? '' : placeHolder;
-										if (tooltip == undefined) tooltip = priv.options.types.number.filterTooltip;
-										tooltip = (tooltip === true || tooltip == undefined) ? 'Values 10 to 20:<br/>10..20<br/>Values exactly 50:<br/>=50' : tooltip === false ? '' : tooltip;
-										elem = $('<input placeholder="{0}" class="filter" type="text" />'.f(placeHolder));
-										elem.on('keyup', {column: column}, priv.filterChanged);
-										break;
-								case "date":
-										if (placeHolder == undefined) placeHolder = priv.options.types.date.placeHolder;
-										placeHolder = (placeHolder === true || placeHolder == undefined) ? '-7..0' : placeHolder === false ? '' : placeHolder;
-										if (tooltip == undefined) tooltip = priv.options.types.date.filterTooltip;
-										tooltip = (tooltip === true || tooltip == undefined) ? 'Today:<br/>0..1<br/>A week today excluded:<br/>-7..0' : tooltip === false ? '' : tooltip;
-										elem = $('<div><input placeholder="{0}" class="filter" type="text" /></div>'.f(placeHolder));
-
-										if (priv.options.types.date.datePicker === true || priv.options.types.date.datePicker == undefined)
-										{
-												if ($().datepicker)
-												{
-														elem.addClass('date-wrap');
-														var today = 0;//new priv.ext.XDate(false).setHours(0, 0, 0, 0).toString('yyyy-MM-dd');
-														var dp = $('<div style="float:right" class="date" data-date="{0}" data-date-format="{1}" />'.f(today, 'yyyy-mm-dd')).appendTo(elem);
-														$('<input style="display:none" type="text"  />').appendTo(dp);
-														$('<span class="add-on"><i class="glyphicon glyphicon-chevron-right"></i></span>').on('click', {op: "l"}, priv.dpOpChanged).appendTo(dp);
-														$('<span class="add-on"><i class="glyphicon glyphicon-chevron-left"></i></span>').on('click', {op: "r"}, priv.dpOpChanged).appendTo(dp);
-														dp.datepicker({weekStart:1});
-														dp.on('changeDate', {column: column, input: $('input.filter', elem)}, priv.dpClicked);
-												}
-												else
-												if (priv.options.debug) console.log('datepicker plugin not found');
-										}
-										elem.on('keyup', 'input.filter', {column: column}, priv.filterChanged);
-										break;
-								case "bool":
-										if (tooltip == undefined) tooltip = priv.options.types.bool.filterTooltip;
-										tooltip = (tooltip === true || tooltip == undefined) ? 'Toggle between:<br/>indeterminate,<br/>checked,<br/>unchecked' : tooltip === false ? '' : tooltip;
-										elem = $('<input class="filter indeterminate" checked type="checkbox" />');
-										elem.on('click', {column: column}, priv.filterChanged);
-										break;
-								case "string":
-										if (placeHolder == undefined) placeHolder = priv.options.types.string.placeHolder;
-										placeHolder = (placeHolder === true || placeHolder == undefined) ? '%' : placeHolder === false ? '' : placeHolder;
-										if (tooltip == undefined) tooltip = priv.options.types.string.filterTooltip;
-										tooltip = (tooltip === true || tooltip == undefined) ? 'Find str: str<br/>Find all but str: !str<br/>Find str inside: %str%' : tooltip === false ? '' : tooltip;
-										elem = $('<input placeholder="{0}" class="filter" type="text" size="8" />'.f(placeHolder));
-										elem.on('keyup', {column: column}, priv.filterChanged);
-										break;
-								case "special":
-										elem = $('<div>&nbsp;</div>');
-										break;
-								case "simpleLink":
-										elem = $('<div>&nbsp;</div>');
-										break;
-								case "geom":
-										if (placeHolder == undefined) placeHolder = priv.options.types.string.placeHolder;
-										placeHolder = (placeHolder === true || placeHolder == undefined) ? '%' : placeHolder === false ? '' : placeHolder;
-										elem = $('<input placeholder="{0}" class="filter" type="text" size="8" />'.f(placeHolder));
-										elem.on('keyup', {column: column}, priv.filterChanged);
-										break;
-								case "none":
-										elem = $('<div>&nbsp;</div>');
-										break;
-						}
-
-						if (false) {// tooltip OFF - (tooltip)
-							elem.tooltip({
-								title: tooltip.trim(),
-								html: true,
-								container: 'body',
-								trigger: 'focus',
-								placement: 'top',
-								delay: {
-									show: 500,
-									hide: 100
-								}
-							});
-						}
-
-						if (elem && props.filter) {
-							$.map(_filterCols, function (colProps, col) {
-								if (col == column) {
-									if (colProps.col.type == 'bool') {
-										if (colProps.filter) elem.prop('checked', true).removeClass('indeterminate');
-										else if (!colProps.filter) elem.prop('checked', false).removeClass('indeterminate');
-										else if (colProps.filter == '') elem.addClass('indeterminate');
-									}
-									else elem.val(colProps.filter);
-								}
-							});
-							if (priv.options.forceFilterInit && undefined !== priv.options.forceFilterInit[column]) {
-								elem.prop('disabled', true);
-							}
-							elem.appendTo(headCell);
-
-							_filterFields[column] = elem;
-						}
-					}
-				}
+				/// console.log('L.<?php echo __LINE__; ?> renderTable::renderTableTheadFilter...');//TODO:DBG:RMME
+				priv.renderTableTheadFilter();
+				_headFilter = true;
 			}
 
 			//create the header special filters row
@@ -1329,6 +1084,277 @@ class TableAjax extends ViewAjax {
 			}
 		};
 
+		priv.renderTableTheadSort = function() {
+			var nodeClass = 'tblAjax__' + 'head__sort',
+					currentNode = _uiNode$Table.find('thead').find('.sort'),
+					node;
+			// currentNode.find('i').tooltip('hide');
+			node = $('<tr class="sort"></tr>');
+			//create the functions column
+			if (priv.options.rowFunctions || priv.options.filtersClean) {
+				var headCell = $('<th class="text-right head-info stickyCol1"></th>').appendTo(node);
+				$.map(priv.options.tblFunctions, function(funObj, funName){
+					var funHtml = $('<a></a>');
+					funHtml.attr('href', funObj.href || '#');
+					if (funObj.title) funHtml.attr('title', funObj.title);
+					if (funObj.icon) funHtml.html('<span class="glyphicon glyphicon-' + funObj.icon + '"></span> ');
+					if (funObj.method && priv[funObj.method] && typeof priv[funObj.method] == 'function') {
+						funHtml.on('click', priv[funObj.method]);
+					}
+					funHtml.appendTo(headCell);
+				});
+			}
+
+			//create the checkall toggle
+			if (_state.uniqueCol && priv.options.checkboxes) {
+				var checked = _checkToggleChecked ? 'checked' : '';
+				var headCell = $('<th></th>').appendTo(node);
+				var elem = $('<input {0} class="checkToggle" type="checkbox" />'.f(checked)).appendTo(headCell);
+				elem.on('change', priv.checkToggleChanged);
+			}
+
+			//create the sortable headers
+			for (var i = 0; i < _state.colsSorted.length; i++) {
+				var column = _state.colsSorted[i];
+				var props = _data.cols[column];
+				if (!props.hidden) {
+					var headCell = $('<th class="ta-ordering"></th>').appendTo(node);
+					if (i == 1) headCell.addClass('stickyCol2');
+
+					if (false) {// TODO: old way
+						var link = $('<a class="pull-left" href="#">{0}</a>'.f(props.friendly || column));
+						link.on('click', {column: column}, priv.columnClicked).appendTo(headCell);
+
+						if (props.tooltip) {
+							$('<i class="glyphicon glyphicon-info-sign"></i>').tooltip({
+								title: props.tooltip.trim(),
+								html: true,
+								container: 'body',
+								placement: "top",
+								delay: {
+									show: 500,
+									hide: 100
+								}
+							}).appendTo(link);
+						}
+
+						//Add sort arrow
+						if (column == _currSortCol) {
+							if (_currSortFlip) $('<i class="glyphicon glyphicon-chevron-down pull-right"></i>').appendTo(headCell);
+							else $('<i class="glyphicon glyphicon-chevron-up pull-right"></i>').appendTo(headCell);
+						}
+
+						//Add hide btn
+						if (column != 'ID') {
+							var hideColBtn = $('<i class="glyphicon glyphicon-remove pull-right hover-show"></i>');
+							hideColBtn.on('click', {column: column},  priv.columnHideClicked);
+							hideColBtn.appendTo(headCell);
+						}
+					}
+
+					if (props.type != 'special' && props.type != 'geom') {
+						headCell.on('click', {column: column}, priv.columnClicked);
+					}
+					var colTitle = column;
+					if (props.description && props.description.length > 0) {
+						colTitle = props.description;
+						colTitle += ' (' + column + ')';
+					}
+					else if (props._tsRetId > 0) {
+						colTitle = 'Kliknij na pole i przejdź do powiązanych rekordów (' + colTitle + ')';
+					}
+
+					if (props.friendly) {
+						var headCnt = $('<span class="pull-left" title="{1}">{0}</span>'.f(props.friendly, colTitle));
+					} else {
+						var headCnt = $('<span class="pull-left" title="{1}">{0}</span>'.f(column, colTitle));
+					}
+					headCnt.appendTo(headCell);
+
+					//Add sort arrow
+					if (column == _currSortCol) {
+						if (_currSortFlip) headCell.addClass('ta-ordering-down');
+						else headCell.addClass('ta-ordering-up');
+					}
+
+					if (column != 'ID') {
+						var hideColBtn = $('<i class="glyphicon glyphicon-remove remove-cell"></i>');
+						hideColBtn.on('click', {column: column},  priv.columnHideClicked);
+						hideColBtn.appendTo(headCell);
+					}
+
+				}
+			}
+
+			currentNode.replaceWith(node);
+		};
+
+		priv.renderTableTheadFilter = function() {
+			var nodeClass = 'tblAjax__' + 'head__filter',
+					currentNode = _uiNode$Table.find('thead').find('.filter'),
+					node;
+			// currentNode.find('i').tooltip('hide');
+			node = $('<tr class="filter"></tr>');
+			//_head.find(".filter").remove();
+			//_headFilter = $('<tr class="filter"></tr>').appendTo(_head);
+			var headCell;
+			var elem;
+			var placeHolder = '';
+			var tooltip = '';
+
+			//create the functions column
+			if (priv.options.rowFunctions || priv.options.filtersClean) {
+				var headCell = $('<th class="text-right stickyCol1"></th>').appendTo(node);
+				if (priv.options.filtersClean) {
+					var elem = $('<button title="Kasuj filtry" class="btn btn-xs btn-link glyphicon glyphicon-remove"></button>').appendTo(headCell);
+					elem.on('click', priv.filtersClean);
+				}
+			}
+
+			//create the filter checkbox
+			if (_state.uniqueCol && priv.options.checkboxes) {
+				tooltip = priv.options.types.bool.filterTooltip || 'Toggle between:<br/>indeterminate,<br/>checked,<br/>unchecked';
+				headCell = $('<th></th>').appendTo(node);
+				elem = $('<input class="filter indeterminate" checked type="checkbox" />').appendTo(headCell);
+				$.map(_filterCols, function (colProps, col) {
+					if (col == "unique") {
+						if (colProps.filter) elem.prop('checked', true).removeClass('indeterminate');
+						else if (!colProps.filter) elem.prop('checked', false).removeClass('indeterminate');
+						else if (colProps.filter == '') elem.addClass('indeterminate');
+					}
+				});
+
+				if (tooltip) {
+					elem.tooltip({
+						title: tooltip.trim(),
+						html: true,
+						container: 'body',
+						trigger: 'hover',
+						placement: 'top',
+						delay: {
+							show: 500,
+							hide: 100
+						}
+					});
+				}
+				elem.on('click', {column: "unique"}, priv.filterChanged);
+			}
+
+			//create the column filters
+			for (var i = 0; i < _state.colsSorted.length; i++) {
+				var column = _state.colsSorted[i];
+				var props = _data.cols[column];
+				tooltip = props.filterTooltip === true ? undefined : props.filterTooltip === false ? '' : props.filterTooltip;
+				placeHolder = props.placeHolder === true ? undefined : props.placeHolder === false ? '' : props.placeHolder;
+
+				if (!props.hidden) {
+					headCell = $('<th></th>').appendTo(node);
+					if (i == 1) headCell.addClass('stickyCol2');
+
+					// @mark MarkTableAjaxFilterColType
+					switch (props.type || 'string') {
+							case "number":
+									if (placeHolder == undefined) placeHolder = priv.options.types.number.placeHolder;
+									placeHolder = (placeHolder === true || placeHolder == undefined) ? '10..20 =50' : placeHolder === false ? '' : placeHolder;
+									if (tooltip == undefined) tooltip = priv.options.types.number.filterTooltip;
+									tooltip = (tooltip === true || tooltip == undefined) ? 'Values 10 to 20:<br/>10..20<br/>Values exactly 50:<br/>=50' : tooltip === false ? '' : tooltip;
+									elem = $('<input placeholder="{0}" class="filter" type="text" />'.f(placeHolder));
+									elem.on('keyup', {column: column}, priv.filterChanged);
+									break;
+							case "date":
+									if (placeHolder == undefined) placeHolder = priv.options.types.date.placeHolder;
+									placeHolder = (placeHolder === true || placeHolder == undefined) ? '-7..0' : placeHolder === false ? '' : placeHolder;
+									if (tooltip == undefined) tooltip = priv.options.types.date.filterTooltip;
+									tooltip = (tooltip === true || tooltip == undefined) ? 'Today:<br/>0..1<br/>A week today excluded:<br/>-7..0' : tooltip === false ? '' : tooltip;
+									elem = $('<div><input placeholder="{0}" class="filter" type="text" /></div>'.f(placeHolder));
+
+									if (priv.options.types.date.datePicker === true || priv.options.types.date.datePicker == undefined)
+									{
+											if ($().datepicker)
+											{
+													elem.addClass('date-wrap');
+													var today = 0;//new priv.ext.XDate(false).setHours(0, 0, 0, 0).toString('yyyy-MM-dd');
+													var dp = $('<div style="float:right" class="date" data-date="{0}" data-date-format="{1}" />'.f(today, 'yyyy-mm-dd')).appendTo(elem);
+													$('<input style="display:none" type="text"  />').appendTo(dp);
+													$('<span class="add-on"><i class="glyphicon glyphicon-chevron-right"></i></span>').on('click', {op: "l"}, priv.dpOpChanged).appendTo(dp);
+													$('<span class="add-on"><i class="glyphicon glyphicon-chevron-left"></i></span>').on('click', {op: "r"}, priv.dpOpChanged).appendTo(dp);
+													dp.datepicker({weekStart:1});
+													dp.on('changeDate', {column: column, input: $('input.filter', elem)}, priv.dpClicked);
+											}
+											else
+											if (priv.options.debug) console.log('datepicker plugin not found');
+									}
+									elem.on('keyup', 'input.filter', {column: column}, priv.filterChanged);
+									break;
+							case "bool":
+									if (tooltip == undefined) tooltip = priv.options.types.bool.filterTooltip;
+									tooltip = (tooltip === true || tooltip == undefined) ? 'Toggle between:<br/>indeterminate,<br/>checked,<br/>unchecked' : tooltip === false ? '' : tooltip;
+									elem = $('<input class="filter indeterminate" checked type="checkbox" />');
+									elem.on('click', {column: column}, priv.filterChanged);
+									break;
+							case "string":
+									if (placeHolder == undefined) placeHolder = priv.options.types.string.placeHolder;
+									placeHolder = (placeHolder === true || placeHolder == undefined) ? '%' : placeHolder === false ? '' : placeHolder;
+									if (tooltip == undefined) tooltip = priv.options.types.string.filterTooltip;
+									tooltip = (tooltip === true || tooltip == undefined) ? 'Find str: str<br/>Find all but str: !str<br/>Find str inside: %str%' : tooltip === false ? '' : tooltip;
+									elem = $('<input placeholder="{0}" class="filter" type="text" size="8" />'.f(placeHolder));
+									elem.on('keyup', {column: column}, priv.filterChanged);
+									break;
+							case "special":
+									elem = $('<div>&nbsp;</div>');
+									break;
+							case "simpleLink":
+									elem = $('<div>&nbsp;</div>');
+									break;
+							case "geom":
+									if (placeHolder == undefined) placeHolder = priv.options.types.string.placeHolder;
+									placeHolder = (placeHolder === true || placeHolder == undefined) ? '%' : placeHolder === false ? '' : placeHolder;
+									elem = $('<input placeholder="{0}" class="filter" type="text" size="8" />'.f(placeHolder));
+									elem.on('keyup', {column: column}, priv.filterChanged);
+									break;
+							case "none":
+									elem = $('<div>&nbsp;</div>');
+									break;
+					}
+
+					if (false) {// tooltip OFF - (tooltip)
+						elem.tooltip({
+							title: tooltip.trim(),
+							html: true,
+							container: 'body',
+							trigger: 'focus',
+							placement: 'top',
+							delay: {
+								show: 500,
+								hide: 100
+							}
+						});
+					}
+
+					if (elem && props.filter) {
+						$.map(_filterCols, function (colProps, col) {
+							if (col == column) {
+								if (colProps.col.type == 'bool') {
+									if (colProps.filter) elem.prop('checked', true).removeClass('indeterminate');
+									else if (!colProps.filter) elem.prop('checked', false).removeClass('indeterminate');
+									else if (colProps.filter == '') elem.addClass('indeterminate');
+								}
+								else elem.val(colProps.filter);
+							}
+						});
+						if (priv.options.forceFilterInit && undefined !== priv.options.forceFilterInit[column]) {
+							elem.prop('disabled', true);
+						}
+						elem.appendTo(headCell);
+
+						_filterFields[column] = elem;
+					}
+				}
+			}
+
+			currentNode.replaceWith(node);
+		};
+
 		priv.renderTableTfoot = function() {
 			_uiNode$Table.find('tfoot').remove();
 			_foot = $('<tfoot></tfoot>').insertAfter(_body);
@@ -1914,8 +1940,9 @@ class TableAjax extends ViewAjax {
 			if (filtersActive) {
 				// TODO: dont remove value from forceFilterInit fields - no field names in search fields?
 				/// TODO: rerender _head (thead.filter)
-				var elems = _head.find('tr.filter').find('input');
-				_head.find('tr.filter').find('input').val('').prop('disabled', false);
+				var elems = _uiNode$Table.find('thead').find('.filter').find('input');
+				elems.val('').prop('disabled', false);
+				elems.removeClass('filter-active');
 				priv.filter();
 			}
 			return false;