Explorar el Código

U render TableAjax filters row

Piotr Labudda hace 6 años
padre
commit
c891b2cd9c
Se han modificado 1 ficheros con 165 adiciones y 132 borrados
  1. 165 132
      SE/se-lib/TableAjax.php.TableAjax.js

+ 165 - 132
SE/se-lib/TableAjax.php.TableAjax.js

@@ -15,6 +15,7 @@ if (!global.createTableDataStateObject) throw "Missing createTableDataStateObjec
 
 var createReactClass = global.p5VendorJs.createReactClass;
 var h = global.p5VendorJs.React.createElement;
+var React = global.p5VendorJs.React;
 var ReactDOM = global.p5VendorJs.ReactDOM;
 var Redux = global.p5VendorJs.Redux;
 var ReduxThunk = global.p5VendorJs.ReduxThunk;
@@ -489,6 +490,78 @@ global['P5UI__TableAjaxSpecialFilters'] = createReactClass({
 	}
 });
 
+global['p5UI__TableAjaxTheadFiltersRow'] = function (props) {
+	DBG && console.log("DBG::TableAjaxTheadFiltersRow ...", { props: props });
+	// props: {
+	// 	namespace: priv.options.namespace,
+	// 	filterStore: priv.options.filterStore,
+	// 	filterActions: priv.options.filterActions,
+	// 	checkboxes: priv.options.checkboxes,
+	// 	primaryKey: _state.primaryKey,
+	// 	colsSorted: _state.colsSorted,
+	// 	_data_cols: _data.cols,
+	// 	rowFunctions: priv.options.rowFunctions,
+	// 	filtersClean: priv.options.filtersClean,
+	// 	forceFilterInit: priv.options.forceFilterInit,
+	// 	checkboxIdContext: priv.options.checkboxIdContext,
+	// }
+	var cellHeight = 24;
+
+	return h(React.Fragment, {}, [
+		(props.filtersClean)
+		?	h(p5UI__TableAjaxClearAllFilters, {
+				style: { padding: '0', height: '' + (cellHeight + 1) + "px" },
+				className: "text-right stickyCol stickyCol1",
+				store: props.filterStore,
+				actions: props.filterActions,
+			})
+		:	(
+				(props.rowFunctions)
+				?	h('th', { className: "text-right stickyCol stickyCol1", style: { padding: '0', height: '' + (cellHeight + 1) + "px" } })
+				:	null
+			)
+		,
+		(props.primaryKey && props.checkboxes)
+		?	h(P5UI__TableAjaxFieldCheckboxSearch, {
+				style: { padding: "0" },
+				className: "stickyCol stickyCol2",
+				namespace: props.namespace,
+				fieldName: ( props.checkboxIdContext ? '@sel_' + props.checkboxIdContext : '@selected' ),
+				store: props.filterStore,
+				actions: props.filterActions
+			})
+		:	null
+		,
+	].concat(
+		props.colsSorted.map(function (fieldName, idx) {
+			var fieldProps = props._data_cols[fieldName];
+			DBG && console.log("DBG::TableAjaxTheadFiltersRow:loop fields", { fieldName, idx, fieldProps });
+			// var tooltip = (fieldProps.filterTooltip === true) ? undefined : ((fieldProps.filterTooltip === false) ? '' : fieldProps.filterTooltip);
+			// var placeHolder = (fieldProps.placeHolder === true) ? undefined : ((fieldProps.placeHolder === false) ? '' : fieldProps.placeHolder);
+			if (fieldProps.hidden) return null;
+
+			return h('th', {
+				style: { padding: 0 },
+				className: (1 === idx) ? "stickyCol stickyCol3" : "",
+			}, [
+				(true) // (fieldProps.filterable)
+				?	h(p5UI__FieldInputFilterSearch, {
+						disabled: (fieldProps.forceFilterInit && undefined !== fieldProps.forceFilterInit[fieldName]),
+						fieldName: fieldName,
+						type: fieldProps.type,
+						lagacyProps: fieldProps, // TODO: use only required like xsdType
+						// xsdType: fieldProps.xsdType,
+						store: props.filterStore,
+						onChange: function (fieldName, value) {
+							props.filterStore.dispatch(props.filterActions.delayFilter(fieldName, value));
+						}
+					})
+				:	null,
+			]);
+		})
+	));
+};
+
 global['P5UI__TableAjaxFieldCheckboxSearch'] = createReactClass({
 	// props.namespace: PropTypes.string.isRequired
 	// props.fieldName: PropTypes.string.isRequired
@@ -504,7 +577,7 @@ global['P5UI__TableAjaxFieldCheckboxSearch'] = createReactClass({
 		return {
 			disabled: this.props.disabled ? true : false,
 			selected: selected,
-			active: ('YES' === selected || 'NO' === selected),
+			isActive: ('YES' === selected || 'NO' === selected),
 			// isLoading: (-1 !== state.loading.indexOf(this.props.fieldName)),
 			// checked: (-1 !== state.selected.indexOf(this.props.fieldName))
 		};
@@ -513,25 +586,25 @@ global['P5UI__TableAjaxFieldCheckboxSearch'] = createReactClass({
 		return this.getStateFromStore();
 	},
 	componentDidMount: function () {
-		DBG && console.log('DBG::P5UI__TableAjaxFieldCheckboxSearch::componentDidMount (f:'+this.props.fieldName+')');
+		DBG && console.log('DBG::TableAjaxFieldCheckboxSearch::componentDidMount (f:'+this.props.fieldName+')');
 		this.unsubscribe = this.props.store.subscribe(this.storeUpdated)
 	},
 	componentWillUnmount: function () {
 		this.unsubscribe()
 	},
 	storeUpdated: function () {
-		DBG && console.log('DBG::P5UI__TableAjaxFieldCheckboxSearch::storeUpdated (f:'+this.props.fieldName+')', this.getStateFromStore());
+		DBG && console.log('DBG::TableAjaxFieldCheckboxSearch::storeUpdated (f:'+this.props.fieldName+')', this.getStateFromStore());
 		this.setState(this.getStateFromStore())
 	},
 	shouldComponentUpdate: function (nextProps, nextState) {
-		DBG && console.log('DBG::P5UI__TableAjaxFieldCheckboxSearch::shouldComponentUpdate (f:'+this.props.fieldName+')', { state: this.state, nextState});
+		DBG && console.log('DBG::TableAjaxFieldCheckboxSearch::shouldComponentUpdate (f:'+this.props.fieldName+')', { state: this.state, nextState});
 		return (
 			this.state.disabled !== nextState.disabled
 			|| this.state.selected !== nextState.selected
 		);
 	},
 	handleChange: function (selected) { // selected: 0 - not checked, 1 - checked, 2 - indeterminate
-		DBG && console.log('DBG::P5UI__TableAjaxFieldCheckboxSearch::handleChange (f:'+this.props.fieldName+')', { selected: selected, state: this.state });
+		DBG && console.log('DBG::TableAjaxFieldCheckboxSearch::handleChange (f:'+this.props.fieldName+')', { selected: selected, state: this.state });
 		if (0 === selected) {
 			this.props.store.dispatch( this.props.actions.setFilter(this.props.fieldName, 'NO') );
 		} else if (1 === selected) {
@@ -548,27 +621,35 @@ global['P5UI__TableAjaxFieldCheckboxSearch'] = createReactClass({
 		}
 	},
 	render: function () {
-		DBG && console.log('DBG::P5UI__TableAjaxFieldCheckboxSearch::render (f:'+this.props.fieldName+')', { props: this.props, state: this.state, state_sel: this.state.selected, sel: this.mapSelectedToValue(this.state.selected) });
-		return h('div',
-			{
-				style: {
-					boxSizing: 'border-box', width: '100%', height: '21px', padding: '0 5px', borderTop: 0,
-					borderBottom: '2px solid ' + ( this.state.active ? '#00ACCC' : 'transparent' ),
-				},
-			}, [
-				h(p5UI__FieldCheckboxSearch, {
-					size: 19,
-					color: '#888',
-					staticLabel: ["Pokaż:", "wszystkie,", "wybrane,", "niewybrane"].join("\n"),
-					fieldName: this.props.fieldName,
-					selected: this.mapSelectedToValue(this.state.selected),
-					onChange: this.handleChange
-					// checked: this.state.checked,
-					// disabled: this.state.disabled,
-					// isLoading: this.state.isLoading,
-				}),
-			]
-		);
+		DBG && console.log('DBG::TableAjaxFieldCheckboxSearch::render (f:'+this.props.fieldName+')', { props: this.props, state: this.state, state_sel: this.state.selected, sel: this.mapSelectedToValue(this.state.selected) });
+		// headCell = $('<th class="stickyCol stickyCol2" style="padding:0"></th>').appendTo(node);
+
+		return h('th', {
+			p5_node_id: "tableAjax_filters_selected",
+			style: Object.assign({}, this.props.style || {}, this.state.isActive ? { backgroundColor: "#d9edf7" } : {}),
+			className: this.props.className || "",
+		}, [
+			h('div',
+				{
+					style: {
+						boxSizing: 'border-box', width: '100%', height: '21px', padding: '0 5px', borderTop: 0,
+						borderBottom: '2px solid ' + (this.state.isActive ? '#00ACCC' : 'transparent'),
+					},
+				}, [
+					h(p5UI__FieldCheckboxSearch, {
+						size: 19,
+						color: (this.state.isActive ? '#000' : '#888'),
+						staticLabel: ["Pokaż:", "wszystkie,", "wybrane,", "niewybrane"].join("\n"),
+						fieldName: this.props.fieldName,
+						selected: this.mapSelectedToValue(this.state.selected),
+						onChange: this.handleChange
+						// checked: this.state.checked,
+						// disabled: this.state.disabled,
+						// isLoading: this.state.isLoading,
+					}),
+				]
+			)
+		]);
 	}
 });
 
@@ -583,7 +664,7 @@ global['p5UI__FieldInputFilterSearch'] = createReactClass({
 		var storeState = this.props.store.getState();
 		return {
 			value: storeState.filter.get(this.props.fieldName) || '',
-			active: storeState.filter.has(this.props.fieldName)
+			isActive: storeState.filter.has(this.props.fieldName)
 		};
 	},
 	getInitialState: function() {
@@ -604,7 +685,7 @@ global['p5UI__FieldInputFilterSearch'] = createReactClass({
 		DBG && console.log('DBG::p5UI__FieldInputFilterSearch::shouldComponentUpdate (f:'+this.props.fieldName+')', { state: this.state, nextState});
 		return (
 			this.state.value !== nextState.value
-			|| this.state.active !== nextState.active
+			|| this.state.isActive !== nextState.isActive
 		);
 	},
 	handleChange: function (event) { // handleChange: function (event) {
@@ -637,13 +718,14 @@ global['p5UI__FieldInputFilterSearch'] = createReactClass({
 	},
 	renderInput: function () {
 		return h('input', {
-			className: "filter", //  + ( this.state.active ? " filter-active" : "" ),
+			className: "filter", //  + ( this.state.isActive ? " filter-isActive" : "" ),
 			placeholder: !this.props.disabled ? "%" : "",
 			type: "text",
 			disabled: this.props.disabled || false,
 			style: {
 				boxSizing: 'border-box', width: '100%', height: '21px', borderTop: 0,
-				borderBottom: '2px solid ' + ( this.state.active ? '#00ACCC' : 'transparent' ),
+				borderBottom: '2px solid ' + (this.state.isActive ? "#00ACCC" : "transparent"),
+				backgroundColor: (this.state.isActive ? "#d9edf7" : "#eee"),
 			},
 			value: this.state.value,
 			onChange: this.handleChange
@@ -657,50 +739,57 @@ global['p5UI__TableAjaxClearAllFilters'] = createReactClass({
 	getStateFromStore: function () {
 		var storeState = this.props.store.getState();
 		return {
-			isFiltersEmpty: ( 0 === storeState.filter.size && 0 === storeState.specialFilter.size )
+			isActive: (storeState.filter.size > 0 || storeState.specialFilter.size > 0)
 		};
 	},
 	getInitialState: function() {
 		return this.getStateFromStore();
 	},
 	componentDidMount: function () {
-		DBG && console.log('DBG::p5UI__TableAjaxClearAllFilters::componentDidMount (f:'+this.props.fieldName+')');
+		DBG && console.log('DBG::TableAjaxClearAllFilters::componentDidMount (f:'+this.props.fieldName+')');
 		this.unsubscribe = this.props.store.subscribe(this.storeUpdated)
 	},
 	componentWillUnmount: function () {
 		this.unsubscribe()
 	},
 	storeUpdated: function () {
-		DBG && console.log('DBG::p5UI__TableAjaxClearAllFilters::storeUpdated (f:'+this.props.fieldName+')', this.getStateFromStore());
+		DBG && console.log('DBG::TableAjaxClearAllFilters::storeUpdated (f:'+this.props.fieldName+')', this.getStateFromStore());
 		this.setState(this.getStateFromStore())
 	},
 	// shouldComponentUpdate: function (nextProps, nextState) {
-	// 	DBG && console.log('DBG::p5UI__TableAjaxClearAllFilters::shouldComponentUpdate (f:'+this.props.fieldName+')', { state: this.state, nextState});
+	// 	DBG && console.log('DBG::TableAjaxClearAllFilters::shouldComponentUpdate (f:'+this.props.fieldName+')', { state: this.state, nextState});
 	// 	return (
 	// 		this.state.value !== nextState.value
 	// 		|| this.state.active !== nextState.active
 	// 	);
 	// },
 	handleClick: function (event) {
-		DBG && console.log('DBG::p5UI__TableAjaxClearAllFilters::handleClick (clearAllFilters)');
+		DBG && console.log('DBG::TableAjaxClearAllFilters::handleClick (clearAllFilters)');
 		this.props.store.dispatch( this.props.actions.clearAllFilters() )
 	},
 	render: function () {
-		DBG && console.log('DBG::p5UI__TableAjaxClearAllFilters::render (clearAllFilters)', { props: this.props, state: this.state });
-		return h('i', {
-			title: this.props.title || "Kasuj wszystkie filtry",
-			className: "glyphicon glyphicon-remove",
-			style: Object.assign(
-				{
-					opacity: '0.5',
-					lineHeight: '20px',
-					padding: '0 3px',
-					cursor: 'pointer',
-				},
-				this.state.isFiltersEmpty ? { color: '#777' } : { color: '#f00' }
-			),
-			onClick: this.handleClick
-		});
+		DBG && console.log('DBG::TableAjaxClearAllFilters::render (clearAllFilters)', { props: this.props, state: this.state });
+
+		return h('th', {
+			p5_node_id: "tableAjax_filters_clearAll",
+			style: Object.assign({}, this.props.style || {}, this.state.isActive ? { backgroundColor: "#d9edf7" } : {}),
+			className: this.props.className || "",
+		}, [
+			h('i', {
+				title: this.props.title || "Kasuj wszystkie filtry",
+				className: "glyphicon glyphicon-remove",
+				style: Object.assign(
+					{
+						opacity: '0.5',
+						lineHeight: '20px',
+						padding: '0 3px',
+						cursor: 'pointer',
+					},
+					this.state.isActive ? { color: '#f00', backgroundColor: "#d9edf7" } : { color: '#777' }
+				),
+				onClick: this.handleClick
+			})
+		]);
 	}
 });
 
@@ -760,9 +849,10 @@ var TableAjax = function() {
 	var _uiNodeSpecialFilters;
 	var _uiNodeFooterInfo;
 	var _uiNode$Table; // the table jQuery node
+	var _uiNodeTheadFiltersRow; // table header columns filter row
 	var _head; // table header
 	var _headSort; // table header sorting row
-	var _headFilter; // table header columns filter row
+	var _headFilter; // table header columns filter row, @used only by priv.renderTable
 	var _headSpecialFilter; // table header special filter row
 	var _bodyNode; // table body
 	var _body; // TODO: table body need render?
@@ -1057,8 +1147,8 @@ var TableAjax = function() {
 		//_uiNode$Table.find('.filter').find('.stickyCol1').css({height:'34px'});
 		var sortStickyColHeight = _uiNode$Table.find('.sort').find('th:last').outerHeight();
 		_uiNode$Table.find('.sort').find('.stickyCol').css({height: sortStickyColHeight + 'px'});
-		var filterStickyColHeight = _uiNode$Table.find('.filter').find('th:last').outerHeight() + 1;
-		_uiNode$Table.find('.filter').find('.stickyCol').css({height: filterStickyColHeight + 'px'});
+		// var filterStickyColHeight = _uiNode$Table.find('.filter').find('th:last').outerHeight() + 1;
+		// _uiNode$Table.find('.filter').find('.stickyCol').css({height: filterStickyColHeight + 'px'});
 		if (priv.options.checkboxes) _uiNode$Table.find('.stickyCol2').css({
 			position: 'absolute',
 			left: '' + (stickyCol1Width) + 'px',
@@ -1112,7 +1202,7 @@ var TableAjax = function() {
 				<_uiNode$Table>
 					<_head>
 						<_headSort />
-						<_headFilter />
+						<_uiNodeTheadFiltersRow />
 					</_head>
 					<_bodyNode />
 					<tfoot /> <!-- @todo: empty? not used? -->
@@ -1126,7 +1216,7 @@ var TableAjax = function() {
 		_uiNode$Table = $('<table class="AjaxTable table table-striped table-hover table-bordered table-condensed"></table>').appendTo(_uiMainContainerNode);
 			_head = $('<thead></thead>').prependTo(_uiNode$Table);
 				_headSort = $('<tr class="sort tblAjax__head__sort"></tr>').prependTo(_head);
-				_headFilter = $('<tr class="filter tblAjax__head__filter"></tr>').appendTo(_head);
+				_uiNodeTheadFiltersRow = $('<tr class="filter tblAjax__head__filter" p5_node_id="tblAjax_filters"></tr>').appendTo(_head).get(0);
 			_bodyNode = $('<tbody></tbody>').insertAfter(_head);
 		$('<tfoot></tfoot>').insertAfter(_bodyNode);
 		_foot = $('<div class="foot tblAjax__footer" style="margin:0; padding:12px; border-top:1px solid #ddd; border-bottom:1px solid #ddd"></div>').insertAfter(_uiMainContainerNode);
@@ -1153,7 +1243,7 @@ var TableAjax = function() {
 		{
 			var topLeftWrap = document.createElement('div')
 			var topRightWrap = document.createElement('div')
-			topWrap.setAttribute('p5_node_name', "topWrap")
+			topWrap.setAttribute('p5_node_id', "tblAjax_topWrap")
 			topWrap.appendChild(topLeftWrap)
 			topWrap.appendChild(topRightWrap)
 			topWrap.style.padding = '12px 0'
@@ -1169,7 +1259,7 @@ var TableAjax = function() {
 		_uiMainContainerNode.parentNode.insertBefore(topWrap, _uiMainContainerNode)
 		var afterTopWrap = document.createElement('div')
 		{
-			afterTopWrap.setAttribute('p5_node_name', "afterTopWrap")
+			afterTopWrap.setAttribute('p5_node_id', "tblAjax_afterTopWrap")
 			afterTopWrap.style.paddingTop = '12px'
 			afterTopWrap.style.borderBottom = '1px solid #ddd'
 			afterTopWrap.style.clear = 'both'
@@ -1182,7 +1272,6 @@ var TableAjax = function() {
 		_head = undefined;
 		_body = undefined;
 		_headSort = undefined;
-		_headFilter = undefined;// TODO: refactor
 	};
 
 	priv.renderTable = function() {
@@ -2089,80 +2178,24 @@ var TableAjax = function() {
 		);
 	};
 
-	priv.renderTableTheadFilter = function() {
-		DBG && console.log('DBG::renderTableTheadFilter...');
-		var nodeClass = 'tblAjax__' + 'head__filter',
-				currentNode = _uiNode$Table.find('thead').find('.' + nodeClass),
-				node;
-		// currentNode.find('i').tooltip('hide');
-		node = $('<tr class="filter ' + nodeClass + '"></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 stickyCol stickyCol1"></th>').appendTo(node);
-			headCell.css({padding: '0'});
-			if (priv.options.filtersClean) {
-				ReactDOM.render(
-					h(p5UI__TableAjaxClearAllFilters, {
-						store: priv.options.filterStore,
-						actions: priv.options.filterActions
-					}),
-					headCell.get(0)
-				);
-			}
-		}
-
-		//create the filter checkbox
-		if (_state.primaryKey && priv.options.checkboxes) {
-			// tooltip = priv.options.types.bool.filterTooltip || 'Pokaż tylko:<br/>nieokreślony,<br/>zaznaczony,<br/>niezaznaczony';
-			headCell = $('<th class="stickyCol stickyCol2" style="padding:0"></th>').appendTo(node);
-			ReactDOM.render(
-				h(P5UI__TableAjaxFieldCheckboxSearch, {
-					namespace: priv.options.namespace,
-					fieldName: ( priv.options.checkboxIdContext ? '@sel_' + priv.options.checkboxIdContext : '@selected' ),
-					store: priv.options.filterStore,
-					actions: priv.options.filterActions
-				}),
-				headCell.get(0)
-			);
-		}
-
-		//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) continue;
-
-			headCell = $('<th></th>').appendTo(node);
-			headCell.css({padding: '0'});
-			if (i == 1) headCell.addClass('stickyCol stickyCol3');
-
-			if (props.filterable === false) continue;
-			ReactDOM.render(
-				h(p5UI__FieldInputFilterSearch, {
-					disabled: (priv.options.forceFilterInit && undefined !== priv.options.forceFilterInit[column]),
-					fieldName: column,
-					type: props.type,
-					lagacyProps: props, // TODO: use ony required like xsdType
-					// xsdType: props.xsdType,
-					store: priv.options.filterStore,
-					onChange: function (fieldName, value) {
-						priv.options.filterStore.dispatch( priv.options.filterActions.delayFilter(fieldName, value) );
-					}
-				}),
-				headCell.get(0)
-			);
-		}
-
-		currentNode.replaceWith(node);
+	priv.renderTableTheadFilter = function () { // _uiNodeTheadFiltersRow
+		DBG && console.log('DBG::renderTableTheadFilter...'); // exec once, at init
+		ReactDOM.render(
+			h(p5UI__TableAjaxTheadFiltersRow, {
+				namespace: priv.options.namespace,
+				filterStore: priv.options.filterStore,
+				filterActions: priv.options.filterActions,
+				checkboxes: priv.options.checkboxes,
+				primaryKey: _state.primaryKey,
+				colsSorted: _state.colsSorted,
+				_data_cols: _data.cols,
+				rowFunctions: priv.options.rowFunctions,
+				filtersClean: priv.options.filtersClean,
+				forceFilterInit: priv.options.forceFilterInit,
+				checkboxIdContext: priv.options.checkboxIdContext,
+			}),
+			_uiNodeTheadFiltersRow
+		);
 	};
 
 	priv.renderTableTfoot = function() {