gerd
11/8/2016 - 2:10 PM

tableNodes_v2.js

/*
 * The tableNodes.js file would contain the logic for table nodes movement.
 * */
jQuery.namespace('lexisnexis.component');
lexisnexis.component.tableNodes1 = lexisnexis.component.Table.extend({
	data : {
		availableTable : [],
		selectedTable : [],
		availableCodes : [],
		selectedCodes: [],
		availableRows : [],
		selectedRows : [],
		scrollAjaxUrl : '',
		searchBoxes : [],
		threshold : LN.THRESHOLD_LIMIT,
		totalRecords : 0,
		viewportRows : 250, 
		thresholdExceedMsg : 'You have exceeded the maximum records (250) that can be selected',
		defaultTableProps : {
			'scrollY' : '200px',
			"sScrollX" : "100%",
			"sScrollXInner" : "140%",
			'scrollCollapse' : false,
			'dom' : 'rtiS',
			'responsive' : true,
			"bAutoWidth" : false,
			"ordering" : true,
			"bFilter" : false,
			"paging" : true,
			"bInfo" : false,
			'aaData' : [],
			"sPaginationType" : "scrolling",
			"bDeferRender": true,
			'columnDefs' : [{
				'render' : function(data, type, row) {
					return '<input type="checkbox" id="chkBox_'+ data + '" value="' + data + '">';
				},
				'targets' : [0],
				'sortable' : false
			}],
			'order' : [[1, 'asc']],
			'serverSide' : true
		}
	},
	/**
	 * To override the fnRecordsDisplay function and the fnMeasure function from the scroller.js file and datatables file.
	 */
	overrideFunctions : function() {
		var cs = this;
		if(LN.THRESHOLD_LIMIT) {
			/**
			 * Overriding the displayBuffer from the SCROLLER.js file to accomodate the number of rows specified from the LN.js 
			 */
			$.fn.DataTable.Scroller.oDefaults.displayBuffer = 2;
			$.fn.DataTable.Scroller.oDefaults.serverWait = 400;
			$.fn.DataTable.Scroller.oDefaults.boundaryScale = 0.9;
			/**
			 * Overridden the fnRecordsDisplay method from the Data Tables to return the configured results only
			 */
			/*$.fn.DataTable.models.oSettings.fnRecordsDisplay = function() {
				var elseRet = !this.aiDisplay.length ? this.aiDisplay.length : this.aiDisplay.length <= LN.THRESHOLD_LIMIT ? this.aiDisplay.length : LN.THRESHOLD_LIMIT;
				return elseRet;
			};*/
			/**
			 * Overriding the fnMeasure function from the scroller.js to display only the configured records.
			 * @param bRedraw
			 */
			$.fn.DataTable.Scroller.prototype.fnMeasure = function(bRedraw) {
				if ( this.s.autoHeight )
				{
					this._fnCalcRowHeight();
				}

				var heights = this.s.heights;

				heights.viewport = $(this.dom.scroller).height();
				this.s.viewportRows = /*parseInt( heights.viewport / heights.row, 10 )*/cs.data.viewportRows;
				this.s.dt._iDisplayLength = parseInt( heights.viewport / heights.row, 10 ) * this.s.displayBuffer;

				if ( bRedraw === undefined || bRedraw )
				{
					this.s.dt.oInstance.fnDraw();
				}
			};
		}
		
		if(typeof Array.prototype.equals == 'undefined') {
			// attach the .equals method to Array's prototype to call it on any array
			Array.prototype.equals = function (array) {
			    // if the other array is a falsy value, return
			    if (!array)
			        return false;

			    // compare lengths - can save a lot of time 
			    if (this.length != array.length)
			        return false;

			    for (var i = 0, l=this.length; i < l; i++) {
			        // Check if we have nested arrays
			        if (this[i] instanceof Array && array[i] instanceof Array) {
			            // recurse into the nested arrays
			            if (!this[i].equals(array[i]))
			                return false;
			        }
			        else if (this[i] != array[i]) {
			            // Warning - two different object instances will never be equal: {x:20} != {x:20}
			            return false;
			        }
			    }
			    return true;
			};
		}
	},
	/**
	 * Create the table using jQuery DataTable
	 */
	createTable : function(tableId,callback){
		var cs = this;
		var $tableId = $('#'+tableId); 
		var obj = {};
		$.extend(obj, cs.data.defaultTableProps, callback.call(cs, tableId));
		$tableId.dataTable().fnDestroy();
		return $tableId.dataTable(obj);
	},
	/**
	 * Gets All the Table Data from the table
	 * specified in the tableId
	 */
	getAllTableData : function(tableId) {
		var $tableId = $('#'+tableId);
		return $tableId.DataTable().settings().data();
	},
	/**
	 * Gets the selected/checked Data from the table
	 * specified in the tableId
	 */
	getSelectedTableData : function(tableId, target) {
		var cs = this;
		var ret = {};
		if(tableId.match('available') || tableId.match('left')) {
			ret = {
				data : cs.data.availableCodes,
				rows : cs.data.availableRows
			};
			if(!cs.checkWithinThreshold(ret.data, $('#'+target).DataTable())) {
				cs.displayMessage();
				return {data : [], rows:[]};
			}
			else {
				cs.data.availableCodes = [];
				cs.data.availableRows = [];
			}
		}
		else {
			/**
			 * The below line of code is used to validate if the selected code is available 
			 * from the correct table when there are two or more selected tables as diagnosis code
			 */
			var dataToBeMoved = $('#' + tableId).DataTable().rows(cs.data.selectedRows).data();
			ret = {
					data : dataToBeMoved,
					rows : cs.data.selectedRows
			};
			cs.data.selectedCodes.pop(dataToBeMoved);
			/*cs.data.selectedCodes = [];*/
		}
		return ret;
	},
	/**
	 * Gets the movable data after evaluating the selected section nodes
	 */
	getMovableData : function(source, target) {
		var cs = this;
		var ret = {};
		var sourceDt = $('#' + source).DataTable();
		if(source.match('available') || source.match('left')) {
			if(cs.data.threshold) {
				var itemsToMoveCount = cs.data.threshold - cs.getTableDataLength(target);
				LN.debug('ItemstoMove Count: ' + itemsToMoveCount);
				if(itemsToMoveCount == 0) {
					cs.displayMessage();
					return { data : []};
				}
				var rowsToMove = $('#' + source + ' tr').slice(0,itemsToMoveCount + 1);
				var output = [];
				var n = sourceDt.rows(rowsToMove).data();
				if(!(n instanceof Array)) {
					/**
					 * Convert it to array
					 */
					var numberOfColumns = 0;
					var tableSettings = n[0];
					if(!(tableSettings instanceof Array)) {
						for(key in tableSettings) {
							if (!isNaN(parseInt(key)) && tableSettings.hasOwnProperty(key)) {
								numberOfColumns = numberOfColumns + 1;
							}
						}
					}
					else {
						numberOfColumns = tableSettings.length;
					}
					for(var i = 0; i < n.length; i++) {
						output.push($.map(n[i], function(value, index){
							if(index < numberOfColumns) {
								return [value];
							}
						}));
					}
				}
				else {
					output = n;
				}
				cs.data.availableCodes = [];
				cs.data.availableRows = [];
				return {
					data : output,
					rows : rowsToMove
				};
			}
		}
		else {
			cs.data.selectedCodes = [];
			cs.data.selectedRows = [];
			return {data : sourceDt.rows($('#' + source + ' tr')).data() };
		}
		
	},
	/**
	 * Get the length of the data from the tableId
	 */
	getTableDataLength : function(tableId) {
		return $('#'+tableId).DataTable().data().length;
	},
	/**
	 * Moves all nodes from source table to target table
	 */
	moveAll : function(source, target) {
		var cs = this;
		var actionSuccess = false;
		var targetEle = $('#' + target);
		var sourceDt = $('#' + source).DataTable();
		var targetDt = $('#' + target).DataTable();
		if(source.match('available') || source.match('left')) {
			if (cs.data.threshold && ((cs.data.totalRecords +  cs.getTableDataLength(target)) > cs.data.threshold)) {
				cs.data.itemsToUncheck = 0;
				cs.displayMessage();
				return false;
			}
		}
		LN.showAjaxIndicator(targetEle.parent());
		var itemsToMove = cs.getMovableData(source, target);
		if (itemsToMove.data.length > 0) {
			targetDt.rows.add(itemsToMove.data);
			if(!itemsToMove.rows) {
				sourceDt.clear();
			}
			else {
				sourceDt.rows(itemsToMove.rows).remove();
			}
			actionSuccess = true;
		}
		LN.hideAjaxIndicator(targetEle.parent());
		return actionSuccess;
	},
	/**
	 * Moves the selected data from source table to 
	 * target table
	 */
	moveSelected : function(source, target) {
		var cs = this;
		var actionSuccess = false;
		var targetEle = $('#' + target);
		var sourceEle = $('#' + source);
		LN.showAjaxIndicator(targetEle.parent());
		var sourceDt = sourceEle.DataTable();
		var targetDt = targetEle.DataTable();
		var itemsToMove = cs.getSelectedTableData(source, target);
		if (itemsToMove instanceof Object && itemsToMove.data.length > 0) {
			targetDt.rows.add(itemsToMove.data);
			/**
			 * Added the if logic to fix the defect DE2141, where after selecting 
			 * and searching the same row was not clearing the search after move
			 */
			if(sourceDt.data().length <= itemsToMove.data.length) {
				sourceDt.clear();
			}
			else {
				sourceDt.rows(itemsToMove.rows).remove();
			}
			actionSuccess = true;
		}
		LN.hideAjaxIndicator(targetEle.parent());
        return actionSuccess;
	}, 
	
	/**
	 * Display the message when the records exceed the maximum limit
	 */
	displayMessage : function() {
		var cs = this;
		//dlg.simpleDialog(cs.data.thresholdExceedMsg.replace('{0}', cs.data.itemsToUncheck || 'some'), "Information", 200, 400, true);		
		var msg = cs.data.thresholdExceedMsg.replace('{0}', cs.data.itemsToUncheck || 'some items from selected filter or modify the search to get apt count of');
		
		$('<div>' + msg + '</div>').dialog({
			modal: true,
			resizable : false,
			show : "slide",
            hide : "puff",
			dialogClass : 'confirmModal',
	        title: 'Warning:  maximum allowed exceeded!',
	        width: 400,
	        height: 300,
	        buttons: {
                Ok: function () {
                    $(this).dialog("close");
                }
            }
	    });
	}, 
	
	/**
	 * Checks whether the target table is within the specified threshold. 
	 * Threshold Limit is specified from LN.js on ready function.
	 * @param data - The items to be moved from the source table
	 * @param targetDt - The target table after DataTable() reinitialization.
	 * @returns Boolean
	 */
	checkWithinThreshold : function (data, targetDt) {
		var cs = this;
		var targetDataLength = targetDt.data().length;
		var ret = true;
		if(cs.data.threshold) {
			if(targetDataLength + data.length > cs.data.threshold) {
				cs.data.itemsToUncheck = data.length - (cs.data.threshold - targetDataLength);
				return false;
			}
		}
		return ret;
	},
	/**
	 * Bind the check box events from the source and target
	 */
	bindCheckboxEvents : function (source, target) {
		var cs = this;
		if(target) {
			sourceAndTargetElems = $('#' + source + ' :checkbox, #' + target + ' :checkbox');
		}
		else {
			sourceAndTargetElems = $('#' + source + ' :checkbox');
		}
		sourceAndTargetElems.off('change');
		sourceAndTargetElems.on('change', function(e){
			e.preventDefault();
			Array.prototype.wrapper_fn = e.currentTarget.checked ? Array.prototype.push : Array.prototype.pop;
			var currentTarget = $(e.currentTarget);
			var closestTr;
			if(currentTarget.parents('table').attr('id').match('available')) {
				cs.data.availableTable = currentTarget.parents('table').DataTable();
				closestTr = currentTarget.closest('tr');
				cs.data.availableRows.wrapper_fn(closestTr);
				var output = [];
				var n = cs.data.availableTable.row(currentTarget.closest('tr')).data();
				if(!(n instanceof Array)) {
					/**
					 * Convert it to array
					 */
					var numberOfColumns = 0;
					for(key in n) {
						if (!isNaN(parseInt(key)) && n.hasOwnProperty(key)) {
							output.push(n[numberOfColumns]);
							numberOfColumns = numberOfColumns + 1;
						} 
					}
				}
				else {
					output = n;
				}
				cs.data.availableCodes.wrapper_fn(output);
			}
			else {
				cs.data.selectedTable = $(currentTarget).parents('table').DataTable();
				closestTr = currentTarget.closest('tr');
				cs.data.selectedRows.wrapper_fn(closestTr);
				cs.data.selectedCodes.wrapper_fn(cs.data.selectedTable.row(currentTarget.closest('tr')).data());
			}
		});
	},
	searchTermsJSON : function() {
		var cs = this;
		var returnJSON = {};
		if(cs.data.searchBoxes && cs.data.searchBoxes.length > 0) {
			$.each(cs.data.searchBoxes, function(index, value){
				returnJSON[value] = typeof $('#'+value + ':visible').val() === 'undefined' ? '' : $('#'+value + ':visible').val();
			});
		}
		return returnJSON;
	},
	timeout : [],
	delay : function ( callback, ms ) {
		clearTimeout( this.timeout );
		this.timeout = setTimeout( callback, ms );
	},
	disableMoveButtons : function() {
		$('[class*="fa-angle"]').parent().addClass('disabled');
	},
	enableMoveButtons : function() {
		$('[class*="fa-angle"]').parent().removeClass('disabled');
	}
});