TimeTrex/interface/html5/global/widgets/ttgrid/TTGrid.js

700 lines
24 KiB
JavaScript
Raw Permalink Normal View History

2022-12-13 07:10:06 +01:00
/**
* @author: joshr@timetrex.com
* @description wrapper class for jqgrid in timetrex.
* Requires free-jqgrid 4.15.4+ and jquery 3.3.1+
*
* @param setup
* @constructor
*/
TTGrid = function( table_id, setup, column_info_array ) {
this.getGridId = function() {
return this.ui_id;
};
this.setTableIDElement = function() {
this.table_id_element = $( '#' + this.ui_id );
return true;
};
this.getTableIDElement = function() {
return this.table_id_element;
};
if ( !table_id || !setup || !column_info_array ) {
Debug.Text( 'ERROR: constructor requires all 3 arguments', 'TTGrid.js', 'TTGrid', 'constructor', 10 );
return;
}
this.ui_id = table_id;
// Issue #2891 - Forcing GridUnload can cause grids inside a AComboBox to disappear after repeated opening. Check for container_selector is to mitigate that.
if ( !setup.container_selector ) {
// We are unloading grids with the same ID if they exist to help prevent: Uncaught TypeError: Failed to execute 'replaceChild' on 'Node': parameter 2 is not of type 'Node'.
// Looping through array in reverse to make sure no index issues after splicing.
for ( var i = LocalCacheData.resizeable_grids.length - 1; i >= 0; i-- ) {
if ( LocalCacheData.resizeable_grids[i] != null && LocalCacheData.resizeable_grids[i].grid != null && LocalCacheData.resizeable_grids[i].ui_id == this.ui_id ) {
LocalCacheData.resizeable_grids[i].grid.jqGrid( 'GridUnload' );
LocalCacheData.resizeable_grids.splice( i, 1 );
} else if ( LocalCacheData.resizeable_grids[i] == null || LocalCacheData.resizeable_grids[i].grid == null ) {
// LocalCacheData.resizeable_grids array gets full of null values from resize event and we are making sure to clear it out.
LocalCacheData.resizeable_grids.splice( i, 1 );
}
}
}
var max_height = null;
this.setTableIDElement();
var table_div = this.getTableIDElement();
this.grid = null;
if ( table_div[0] == false ) {
Debug.Text( 'ERROR: table_id not found in DOM', 'TTGrid.js', 'TTGrid', 'constructor', 10 );
return;
}
//Default grid settings.
var default_setup = {
container_selector: 'body',
sub_grid_mode: false,
altRows: true,
data: [],
datatype: 'local',
//quickEmpty: 'true', //Default is 'quickest', might fix JS Exception: Uncaught TypeError: Failed to execute 'replaceChild' on 'Node': parameter 2 is not of type 'Node', but causes this instead: TTGrid.js?v=11.6.1-20191108:99 Uncaught TypeError: Cannot read property 'cells' of undefined
sortable: false,
height: table_div.parents( '.view' ).height(),
width: table_div.parent().width(),
rowNum: 10000,
colNames: [],
colModel: column_info_array,
multiselect: true,
multiselectWidth: 22,
multiboxonly: true,
viewrecords: true,
autoencode: true,
scrollOffset: 0,
verticalResize: true, //when the grid resizes do we reisize it vertically? needed for timesheet and subgrid views.
resizeGrid: true,
winMultiSelect: true
// resizeStop: function(width, index){
// //$this.setGridColumnsWidth(width, index);
// }
};
if ( setup.max_height === true ) {
setup.max_height = max_height;
}
if ( setup ) {
setup = $.extend( {}, default_setup, setup );
} else {
setup = default_setup;
}
this.setup = setup;
table_div.empty(); //should unbind all events bound to the grid.
this.grid = table_div.jqGrid( setup );
LocalCacheData.resizeable_grids.push( this );
if ( setup.winMultiSelect === true ) {
this.grid.winMultiSelect();
}
//turn off grid resize event (for schedule grids that need to be rebuilt on every resize)
this.noResize = function() {
this.setup.onResizeGrid = false;
};
/**
*
* @param data
*/
this.setData = function( data, clear_grid ) {
if ( this.grid ) {
//Clear grid by default.
clear_grid = ( clear_grid == null ) ? true : clear_grid;
if ( clear_grid == true ) {
this.grid.clearGridData();
}
//ACombo might send data as "true" when the unselected grid is blank and "Show All" is clicked. Prevent anything but an array from being passed into setGridParam( 'data' ).
if ( Array.isArray( data ) == false ) {
data = [];
}
this.grid.setGridParam( { 'data': data } ).trigger( 'reloadGrid' );
//this.setGridColumnsWidth();
} else {
throw( 'ERROR: Grid is not ready yet.' );
}
};
this.getData = function() {
return this.getGridParam( 'data' );
};
this.getSetup = function() {
return this.getGridParam( 'data' );
};
this.getHeight = function() {
return $( this.grid ).height();
};
this.getWidth = function() {
return $( this.grid ).width();
};
/**
*
* @param value
*/
this.deleteRow = function( value ) {
this.grid.jqGrid( 'delRowData', value );
};
this.resetSelection = function() {
this.grid.resetSelection();
};
this.setSelection = function( x1, y1, x2, y2, noScale ) {
this.grid.setSelection( x1, y1, x2, y2, noScale );
};
this.getGridParam = function( parameter_name ) {
return this.grid.getGridParam( parameter_name );
};
this.setGridParam = function( parameter_name, value ) {
return this.grid.setGridParam( parameter_name, value );
};
this.unload = function() {
if ( this.grid ) {
this.grid.jqGrid( 'GridUnload' );
this.grid = null;
}
return true;
};
this.clearGridData = function() {
this.grid.jqGrid( 'clearGridData', true );
};
this.reloadGrid = function() {
this.grid.trigger( 'reloadGrid' );
};
this.getRecordFromGridById = function( id ) {
var data = this.grid.getGridParam( 'data' );
var result = null;
/* jshint ignore:start */
//id could be string or number.
$.each( data, function( index, value ) {
if ( value['_id_'] == id ) {
result = Global.clone( value );
return false;
}
} );
/* jshint ignore:end */
if ( result ) {
result.id = result['_id_'];
}
return result;
};
this.getGridWidth = function() {
if ( this.grid ) {
return this.grid.width();
}
return 0;
};
this.setGridWidth = function( w, inner_width ) {
if ( this.grid ) {
if ( inner_width > w ) {
w = inner_width;
}
this.grid.setGridWidth( w );
}
};
this.getGridHeight = function() {
if ( this.grid ) {
return this.grid.height();
}
return 0;
};
this.setGridHeight = function( h ) {
if ( this.setup.static_height ) {
h = this.setup.static_height;
}
if ( this.grid ) {
this.grid.setGridHeight( h );
}
};
this.setRowData = function( id, new_record ) {
this.grid.setRowData( id, new_record );
};
this.getRowData = function( row_id ) {
var row = false;
var row_data = this.getData();
for ( var i in row_data ) {
if ( row_data[i].id == row_id ) {
row = row_data[i];
break;
}
}
return row;
};
this.getColumnModel = function() {
return this.getGridParam( 'colModel' );
};
this.setColumnModel = function( val ) {
this.getGridParam( 'colModel', val );
};
this.grid2csv = function( filename ) {
// TODO: Add in more robust quote escaping to handle data strings that have quotes. Currently we are just wrapping everything in double quotes.
let csv_data = [];
// Get grid data for csv.
// Column headers are in a different table. Seems to be a jqGrid thing?
// Parsing column headers using aria-describedby on the first none blank <tr> (2nd) which links to the id of the header and from there gets the textContent.
let i = 1;
let headers = [];
for ( let tr of document.querySelectorAll( '#' + this.getGridId() + ' tr' ) ) {
let row = [];
for ( let td of tr.querySelectorAll( 'td' ) ) {
row.push( '"' + td.textContent.trim() + '"' );
if ( i === 2 ) {
// Column headers sometimes contain HTML such as Claim<br>Dependents.
// Using a temporary element to replace <br> with a space and then grabbing the textContent to strip the HTML.
let temp_element = document.createElement( 'div' );
temp_element.innerHTML = document.getElementById( td.getAttribute( 'aria-describedby' ) ).innerHTML.replace( '<br>', ' ' );
headers.push( '"' + temp_element.textContent.trim() + '"' );
}
}
csv_data.push( row.join( ',' ) );
i++;
}
// Replace blank row with table headers
csv_data[0] = headers.join( ',' );
let csv_content = csv_data.join( '\r\n' );
Global.JSFileDownload( filename + '.csv', csv_content, 'text/csv;encoding:utf-8' );
}
this.getRecordCount = function() {
if ( !this.grid ) {
return false;
}
return this.grid.getGridParam( 'reccount' );
};
//Gets a single row
this.getSelectedRow = function() {
if ( !this.grid ) {
return false;
}
var result = this.grid.getGridParam( 'selrow' );
if ( !result ) {
result = false;
}
return result;
};
//Gets an array of rows if multiple are selected.
this.getSelectedRows = function() {
if ( !this.grid ) {
return []; //Return empty array so .length on the result doesn't fail with Cannot read property 'length' of undefined
}
var result = this.grid.getGridParam( 'selarrrow' );
if ( !result ) {
result = [];
}
return result;
};
this.getSelection = function() {
var tds = this.grid.find( 'td.ui-state-highlight' );
var selection = [];
for ( var x = 0; x < tds.length; x++ ) {
selection.push( {
tr: $( tds[x] ).parent( 'tr' ).index(),
td: $( tds[x] ).index()
} );
}
return selection;
},
this.setTimesheetSelection = function( selection_obj ) {
//This is currently broken, it highlights the cells, but they aren't actually considered "selected".
// So if you go to Attendance -> TimeSheet, select two cells, Mass Edit them, click Save, the "Mass Edit" is no longer available to be clicked again.
// As well if you hold in SHIFT to try and expand the selection (select more cells), that doesn't work either.
var trs = this.grid.find( 'tr' );
for ( var i = 0; i < selection_obj.length; i++ ) {
for ( var x = 0; x < trs.length; x++ ) {
if ( $( trs[x] ).index() == selection_obj[i].tr ) {
var tds = $( trs[x] ).find( 'td' );
for ( var w = 0; w < tds.length; w++ ) {
if ( $( tds[w] ).index() == selection_obj[i].td ) {
$( tds[w] ).addClass( 'ui-state-highlight' );
break;
}
}
break;
}
}
}
};
this.setGridColumnsWidth = function( column_model, options ) {
// this.grid.autoResizeAllColumns();
// return;
if ( this.setup.treeGrid || this.setup.tree_mode ) {
this.setGridWidth( $( this.setup.container_selector ).width() - 12 );
return;
}
if ( typeof options === 'undefined' ) {
options = {};
}
if ( this.setup.container_selector && ( !options.min_grid_width || options.min_grid_width == 0 ) ) {
var parent_container = this.grid.parents( this.setup.container_selector ).find( '.edit-view-tab' );
if ( parent_container.length > 0 ) {
//Sub-View grid, check if parent div is visible, and if not don't bother resizing grid.
if ( parent_container.is( ':visible' ) === true ) {
options.min_grid_width = parent_container.innerWidth();
} else {
Debug.Text( ' Parent container of grid is not visible, skip setting column widths...', 'TTGrid.js', 'TTGrid', 'setGridColumnsWidth', 10 );
return;
}
} else {
//Main grid
let grid_parent = $( '#gbox_' + this.ui_id );
if ( grid_parent.length !== 0 ) {
options.min_grid_width = grid_parent.parent().width();
} else {
options.min_grid_width = this.grid.parents( this.setup.container_selector ).innerWidth();
}
}
}
if ( options.min_grid_width == 0 || options.min_grid_width == 'undefined' ) { //fallback width so it's never sized to zero when render timing collides
options.min_grid_width = $( 'body' ).innerWidth();
}
//Adjust for the vertical scrollbar offset that can occur when the items per page always exceeds the screen height.
if ( Global.isVerticalScrollBarRequired( this.grid.parents( '.ui-jqgrid-bdiv' )[0] ) ) {
options.min_grid_width -= Global.getScrollbarWidth();
}
if ( !options.max_grid_width ) {
options.max_grid_width = null; //No maximum.
}
if ( options.max_grid_width && options.max_grid_width < options.min_grid_width ) {
options.min_grid_width = options.max_grid_width;
}
Debug.Text( 'Target Grid: ' + this.setup.container_selector + ' Target Div: ' + this.grid.parents( this.setup.container_selector ).id + ' Width: Min: ' + options.min_grid_width + ' Max: ' + options.max_grid_width + ' Scrollbar Offset: ' + Global.getScrollbarWidth() + ' Parent Width: ' + $( this.grid.parents( '.edit-view-tab, body' )[0] ).width(), 'TTGrid.js', 'TTGrid', 'setGridColumnsWidth', 10 );
if ( column_model ) {
var total_column_width = 0;
for ( var i = 0; i < column_model.length; i++ ) {
var field = column_model[i].name;
var width = column_model[i].width ? column_model[i].width : column_model.widthOrg;
total_column_width += width;
//Don't change the width of columns if they are already the same size. This may help avoid minor changes in the table caused by simple redraws.
if ( this.grid.getColProp( field ).width != width ) {
this.grid.setColWidth( field, width );
}
}
return total_column_width;
}
var column_model = this.getColumnModel();
//Possible exception
//Error: Uncaught TypeError: Cannot read property 'length' of undefined in /interface/html5/#!m=TimeSheet&date=20141102&user_id=53130 line 4288
if ( !column_model ) {
Debug.Text( 'ERROR: column_model is null or undefined', 'TTGrid.js', 'TTGrid', 'setGridColumnsWidth', 10 );
return;
}
function longer( champ, contender ) {
return ( contender.length > champ.length ) ? contender : champ;
}
function longestWord( str ) {
if ( str && typeof str === 'string' ) {
var words = str.split( ' ' );
return words.reduce( longer );
} else {
return '';
}
}
var grid_data = this.getData();
this.grid_total_width = 0;
var cb_column_width = 0; //checkbox column width, usually 22, but only set once we know there is a checkbox column.
var cb_column_count_adjustment = 0; //If the checkbox column exists or not.
var longest_field_width = 0;
var last_column = null;
var column_widths = {};
for ( var i = 0; i < column_model.length; i++ ) {
var col = column_model[i];
last_column = col;
var field = col.name;
var longest_cell_content = longestWord( col.label ); // allow extra space for sort order UI hint
var header_is_longest = true;
if ( field == 'cb' ) { //hard coded override on CB column, so we don't try to check the data in each row for it.
cb_column_count_adjustment = 1;
cb_column_width = 22;
width = cb_column_width;
} else {
if ( options.column_width_override && options.column_width_override[field] ) {
width = options.column_width_override[field];
} else {
for ( var j = 0; j < grid_data.length; j++ ) {
var row_data = grid_data[j];
if ( !row_data.hasOwnProperty( field ) ) {
break;
}
var current_cell_content = row_data[field];
if ( !current_cell_content ) {
current_cell_content = '';
}
if ( !longest_cell_content ) {
longest_cell_content = current_cell_content.toString();
header_is_longest = false;
} else {
if ( current_cell_content && current_cell_content.toString().length > longest_cell_content.length ) {
longest_cell_content = current_cell_content.toString();
header_is_longest = false;
}
}
}
var calculate_text_width_options;
if ( longest_cell_content == field ) {
calculate_text_width_options = { fontSize: '11px', fontWeight: 'bolder' };
} else {
calculate_text_width_options = { fontSize: '11px', fontWeight: 'normal' };
}
var width = Global.calculateTextWidth( longest_cell_content, calculate_text_width_options ); // + 40; // 8 is drag handle width +2 for borders +20 for sort order ui hint (17 for actual hint,13 for header padding on Firefox under windows
if ( header_is_longest === true ) {
width += 40;
} else {
width += 12;
}
}
}
if ( width > longest_field_width ) {
longest_field_width = width;
}
//Debug.Text( ' Column: '+ field +' Width: '+ width +' Content: \''+ longest_cell_content +'\' Longest Column Width: '+ longest_field_width +' Header is Longest: '+ header_is_longest, 'TTGrid.js', 'TTGrid', 'setGridColumnsWidth', 10 );
column_widths[field] = width;
this.grid_total_width += width;
}
//If the longest column width can be used for all columns, size them all equally so they don't change sizes between pages.
if ( ( longest_field_width * column_model.length ) <= options.min_grid_width ) {
var equal_column_width = Math.floor( ( options.min_grid_width - cb_column_width ) / ( column_model.length - cb_column_count_adjustment ) );
var equal_column_width_remainder = ( ( options.min_grid_width - cb_column_width ) % ( column_model.length - cb_column_count_adjustment ) ); //Eliminate partial pixel adjustments.
Debug.Text( ' Grid columns CAN fit with equal sizes... Grid Width: ' + options.min_grid_width + ' Optimal Grid Width: ' + this.grid_total_width + ' Equal Size Width: ' + equal_column_width + ' Remainder: ' + equal_column_width_remainder, 'TTGrid.js', 'TTGrid', 'setGridColumnsWidth', 10 );
var adjusted_grid_width = 0;
var x = 0;
for ( var tmp_column_name in column_widths ) {
if ( tmp_column_name == 'cb' ) {
this.grid.setColWidth( 'cb', cb_column_width );
adjusted_grid_width += cb_column_width;
} else {
var tmp_column_width = equal_column_width;
if ( x == 1 ) {
tmp_column_width += equal_column_width_remainder;
}
//Debug.Text( ' Adjusted Column: '+ tmp_column_name +' Width: Old: '+ column_widths[tmp_column_name] +' New: '+ tmp_column_width, 'TTGrid.js', 'TTGrid', 'setGridColumnsWidth', 10 );
if ( this.grid.getColProp( tmp_column_name ).width != tmp_column_width ) {
this.grid.setColWidth( tmp_column_name, tmp_column_width );
}
adjusted_grid_width += tmp_column_width;
}
this.grid.setColProp( tmp_column_name, 'fixed', true );
x++;
}
Debug.Text( ' Adjusted Grid Width: ' + adjusted_grid_width + ' Adjusted Column Remainder: ' + equal_column_width_remainder, 'TTGrid.js', 'TTGrid', 'setGridColumnsWidth', 10 );
this.grid_total_width = options.min_grid_width;
} else {
Debug.Text( ' Optimal Grid Width: ' + this.grid_total_width + ' Equal Size Width: ' + ( longest_field_width * column_model.length ), 'TTGrid.js', 'TTGrid', 'setGridColumnsWidth', 10 );
var body_width_difference = 0;
var column_width_adjustment = 0;
var columns_to_adjust_width = 0;
var column_width_adjustment_remainder = 0;
//If the optimal column widths are wider than the max grid width, shrink them to fit.
if ( ( options.max_grid_width > 0 && this.grid_total_width > options.max_grid_width ) || ( options.min_grid_width > 0 && this.grid_total_width < options.min_grid_width ) ) {
//When columns are too small to fit on the screen and need to be stretched, ignore the overridden column.
if ( ( options.max_grid_width > 0 && this.grid_total_width > options.max_grid_width ) ) {
body_width_difference = this.grid_total_width - options.max_grid_width; //Should be a negative difference to shrink columns to fit max width.
this.grid_total_width = options.max_grid_width;
} else {
body_width_difference = options.min_grid_width - this.grid_total_width; //Should be a positive difference to grow columns to fit min width.
this.grid_total_width = options.min_grid_width;
}
if ( body_width_difference != 0 ) {
if ( options.column_width_override ) {
columns_to_adjust_width = ( column_model.length - options.column_width_override.length() );
} else {
columns_to_adjust_width = ( column_model.length - cb_column_count_adjustment );
}
column_width_adjustment = Math.floor( body_width_difference / columns_to_adjust_width );
column_width_adjustment_remainder = ( body_width_difference % columns_to_adjust_width ); //Eliminate partial pixel adjustments.
}
}
var adjusted_grid_width = 0;
var x = 0;
for ( var tmp_column_name in column_widths ) {
if ( tmp_column_name == 'cb' ) {
this.grid.setColWidth( 'cb', cb_column_width );
adjusted_grid_width += cb_column_width;
} else {
var tmp_column_width;
if ( options.column_width_override && options.column_width_override[n] ) {
tmp_column_width = column_widths[tmp_column_name];
} else {
tmp_column_width = column_widths[tmp_column_name] + column_width_adjustment;
}
if ( x == 1 ) { //First column after the CB.
tmp_column_width += column_width_adjustment_remainder;
}
Debug.Text( ' Adjusted Column: ' + tmp_column_name + ' Width: Old: ' + column_widths[tmp_column_name] + ' New: ' + tmp_column_width + ' Adjustment: ' + column_width_adjustment + ' Body Difference: ' + body_width_difference + ' Columns Adjusted: ' + columns_to_adjust_width, 'TTGrid.js', 'TTGrid', 'setGridColumnsWidth', 10 );
if ( this.grid.getColProp( tmp_column_name ).width != tmp_column_width ) {
this.grid.setColWidth( tmp_column_name, tmp_column_width );
}
adjusted_grid_width += tmp_column_width;
}
this.grid.setColProp( tmp_column_name, 'fixed', true );
x++;
}
//Debug.Text( ' Adjusted Grid Width: '+ adjusted_grid_width +' Adjusted Column Remainder: '+ column_width_adjustment_remainder, 'TTGrid.js', 'TTGrid', 'setGridColumnsWidth', 10 );
}
//this.setGridWidth( this.grid_total_width, this.grid_total_width ); //Causes columns with to flucuate, specifically in schedule day mode.
Debug.Text( ' FINAL Grid width: ' + this.grid_total_width + ' Body Width: ' + Global.bodyWidth() + ' Total Rows: ' + grid_data.length, 'TTGrid.js', 'TTGrid', 'setGridColumnsWidth', 10 );
return this.grid_total_width;
};
//resize event.
$( window ).off( 'resize.grids' ).on( 'resize.grids', Global.debounce( ( e ) => this.TTGridResizeEvent( e ), 500 ) );
this.TTGridResizeEvent = function( e ) {
e.stopPropagation();
Debug.Text( ' Window resize event hit by TTGrid. Target: ' + e.target, 'TTGrid.js', 'TTGrid', 'setGridColumnsWidth', 10 );
if ( LocalCacheData.resizeable_grids.length > 0 ) {
//remove the nulls
var grids = LocalCacheData.resizeable_grids.filter( function( t ) {
return t != null;
} );
LocalCacheData.resizeable_grids = grids;
for ( var i in LocalCacheData.resizeable_grids ) {
var ttgrid = LocalCacheData.resizeable_grids[i];
if ( !ttgrid || ( typeof ttgrid.getTableIDElement === 'function' && ttgrid.getTableIDElement().length === 0 ) || !ttgrid.grid || ttgrid.setup.onResizeGrid === false ) {
Debug.Arr( LocalCacheData.resizeable_grids, ' Grid ignored ' + i, 'TTGrid.js', 'TTGrid', 'setGridColumnsWidth', 10 );
LocalCacheData.resizeable_grids[i] = null;
continue;
}
//Try to only resize visible grids. ie: Switch from Audit tab to primary tab, wait until resize event is triggered, then switch back, triggering "flashing" of scroll bars appearing/disappearing
// Only happens on edit views with double row fields (ie: Note fields), like Edit Punch or Edit Schedule.
if ( ttgrid.getTableIDElement().is( ':visible' ) ) {
Debug.Text( ' Processing: ' + ttgrid.ui_id, 'TTGrid.js', 'TTGrid', 'setGridColumnsWidth', 10 );
if ( ttgrid.setup.onResizeGrid && typeof ttgrid.setup.onResizeGrid == 'function' ) {
Debug.Text( ' TTGrid invoked setup defined onResizeGrid() for ' + ttgrid.ui_id, 'TTGrid.js', 'TTGrid', 'setGridColumnsWidth', 10 );
ttgrid.setup.onResizeGrid();
} else {
if ( ttgrid.grid.length == 1 ) {
Debug.Text( ' TTGrid invoked TTgrid::setGridColumnsWidth() for ' + ttgrid.ui_id, 'TTGrid.js', 'TTGrid', 'setGridColumnsWidth', 10 );
ttgrid.setGridColumnsWidth();
}
}
} else {
Debug.Text( ' Skipping grid that is not visible: ' + ttgrid.ui_id, 'TTGrid.js', 'TTGrid', 'setGridColumnsWidth', 10 );
}
}
//Usually we will want to make double sure that visible search grids resize.
//Have to check for grid though because dashboard has no "search grid"
if ( LocalCacheData.current_open_primary_controller && LocalCacheData.current_open_primary_controller.grid ) {
LocalCacheData.current_open_primary_controller.setGridColumnsWidth(); //Be sure to call the setGridColumnsWidth() from current_open_primary_controller in case its overridden.
LocalCacheData.current_open_primary_controller.setGridSize();
}
//Also resize grids inside Edit Views.
if ( LocalCacheData.current_open_sub_controller && LocalCacheData.current_open_sub_controller.grid ) {
LocalCacheData.current_open_sub_controller.setGridColumnsWidth(); //Be sure to call the setGridColumnsWidth() from current_open_sub_controller in case its overridden.
LocalCacheData.current_open_sub_controller.setGridSize();
}
}
}
};