~~Title: Data Grid API~~

<html><font color=#990000 size="+2"><b>Data Grid API</b></font></html>

The <color #00a2e8>Grid Control</color> is a rubust data structure capable of rendering data in //Tabular// or //Tree// views.
When the grid API is used, it alters the visible, cached content of a ''grid''.  This is what is displayed on the canvas by default,
unless a ''gridControl.resetData()'' method is called.  This resets content and performs a cache merge.  Therefore if the initial grid
values are populated from the back-end system, and the API is used to manipulate them, the user will only see the chaned, //cached// 
versionn and not the actual results from the //data fech// operation.  In this example //gridContol// is the name of the grid control.

\\
''addRow(row)'' - append row object to the end.
  * returns boolean true/false to indicate if row was added(true) or ignored(false) in case it's duplicate and grid option 'uniqueIdConstraint'=true;

''insertRow(row, index = 0)'' - insert row on index (index 0 by default so to the beginning)
  * returns boolean true/false to indicate if row was added(true) or ignored(false) in case it's duplicate and grid option 'uniqueIdConstraint'=true;

''removeRow(id)'' - remove row by id

''removeRowAt(index = 0)'' - remove row at index

''removeRows(column, value)'' - remove all rows where chosen column has specified value.
  * If "column" is string - first column with given header will be used.
  * If "column" is number - it will be used as zero-based column index, so column=0 means first column in the grid.

''getRow(id)'' - find row by id

''findRow(column, value)'' - find first row, where chosen column has specified value.
  * If "column" is string - first column with given header will be used.
  * If "column" is number - it will be used as zero-based column index, so column=0 means first column in the grid.
  * Returns row object or 'undefined' if not found.

''findRows(column, value)'' - find all rows, where chosen column has specified value.
  * If "column" is string - first column with given header will be used.
  * If "column" is number - it will be used as zero-based column index, so column=0 means first column in the grid.
  * Returns array, empty if nothing found.

''value'' - is a variable that holds an array of selected Rows Id, can set/get

''selectionHash'' - is a variable that holds a sequence of row numbers in the order they were selected 

''getSelectedRows()'' - returns array of row objects

''setSelectedRows()'' - expects array of row objects and updates grid.value internally

''clearRows()'' - remove all rows

''resetData()'' - resets and merges visible grid contents, re-enabling data fetch from back-end

''data'' - API property to access data array.
  * Returns detached copy, so modifying array will not affect grid untill assigned back to property explicitly.

\\
=== Examples ===

Changing the contents of a data copy:

<sxh DSQL; gutter: true;>
  /* no effect, first item removed from the copy.*/
  myGrid.data.shift(); 
  /* save copy to var */
  var data = myGrid.data; 
  /* change copy contents */
  data.shift(); 
  /* Here we overwrite grid data explicitly. */
  myGrid.data = data; 
</sxh>

Accessing underlying row objects inside ''grid.data'' directly, allows you to manipulate the data grid's 
underlying //data array//.  The ''grid.data'' is an array of arrays expressed as indexed data rows and cells.
Their vaues can be set individually, or as ''Row'' objects.  The following example sets the first cell of 
the first row and then adds another row to the grid:

<sxh DSQL; gutter: true;>
  /* this affects grid data directly */
  myGrid.data[0].cells[0]="Hello"; 
  
  var row = { cells: [ {text: "Tester Accounting 1"}, {text: "Bobbie McGee"}] };
  myGrid.addRow(row);
</sxh>

The ''grid'' object API also allows users to load contents directly, reset the grid for re-use and //render// the
contents after data has changed. When ''grid.data'' is bound to a //Data Source// result it may ned to be //reset//
in order to synchronize with the source or the cache.  Note that ''Row'' objects, expressed as //JSON// can take
//data type// assignments like ''text'' or ''value'' to set specific aspects of a cell element.  The actual data
type is dependent on the type of object stored in the //cell//.  For example //icons// can potentially take //url//
data that contains binary content that can set the image of a cell.  The limited exaple below illustrates only 
aspects of label or checkbox controls:

<sxh DSQL; gutter: true;>
  // Lookup the data grid control
  var dataGrid = component.getControl('grd_tribeSelect');
  // clear all previous contents
  dataGrid.clearRows();
  // reset data sync (in case were bound to result sets)
  dataGrid.resetData();
  // reset grid selection (if enabled)
  dataGrid.value = null;
  // Add some rows
  var row = { cells: [ {text: "Tester Accounting 1"}, {text: "Jonnie Joyce"}, {value: "false"} ] };
  dataGrid.addRow(row);
      row = { cells: [ {text: "Tester Accounting 2"}, {text: "Samuel Jackson"}, {value: "false"} ] };
  dataGrid.addRow(row);
  // Log contents..
  console.log('Adding Row: ', row );
  // render the contents after manual update
  dataGrid.render();
</sxh>

Itereating over rows of underlying ''grid.data'' directly:

<sxh DSQL; gutter: true;>
    for(let i = 0; i < dataGrid.data.length; i++) {
        const row = dataGrid.data[i];
        console.log('Row #'+i, row);
        console.log('isChecked: ' + row.cells[2].isChecked);
    }
</sxh>

Obtaining and processing an array of selected //row elements//  of underlying ''grid.data'':

<sxh DSQL; gutter: true;>
  var tribeList = component.getControl('grd_tribeList');
  
  const selected = (String(dataGrid.selectionHash).slice(1, -1)).split(",");
  
  selected.forEach( function(idx) {
      // console.log('Selected Row[' + idx + ']: ', dataGrid.data[idx]);
      var row = dataGrid.data[idx];
      tribeList.addRow(row);
      });
  
  tribeList.render();
  
  var win = component.getControl('ovr_tribeList');
  win.setVisible(false);
</sxh>
  
The above example gets selected row elements and then adds the to another data grid, illustrating how a typical choice selection window can be implemented. Note that render is called at the end, prior to //hiding// the underlying panel.  Making the panel visible again will retain the original choices.  To affect //re-load// behavior a grid control should be reset and potentially a //data fetch// and //render// operation should be called in the ''ready'' trigger. 

\\
=== Working with Grid Elements ===
\\
The ''grid API'' allows users to managed and manipulate grid contents directly independent of any back-end data.  If the control is not //bound// to 
result data the user may still access the results directly and use them to populate grid controls.  Alternativley, grid control data may be accessed
direclty and loded with arbitrary //row// values.  This can be ueful when caching large amounts of tabular data or creating advanced list components.

Examples:

<sxh DSQL; gutter: true;>
  // Lookup the Grid Control
  var dataGrid = component.getControl('grd_dealsSelect');
  // Clear all previous contents
  dataGrid.clearRows();
  
  var row = { cells: [ {text: "Tester Accounting 1"}, {text: "Jonnie Joyce"}, {value: "false"} ] };
  dataGrid.addRow(row);
      row = { cells: [ {text: "Tester Accounting 2"}, {text: "Samuel Jackson"}, {value: "false"} ] };
  dataGrid.addRow(row);
      row = { cells: [ {text: "Tester Accounting 3"}, {text: "Ron Taylor"}, {value: "false"} ] };
  dataGrid.addRow(row);
      row = { cells: [ {text: "Tester Accounting 4"}, {text: "Bill Bixby"}, {value: "false"} ] };
  dataGrid.addRow(row);
  
  dataGrid.render();
</sxh>  

\\
=== Applying Styles to Grid Elements ===
\\

''grid.selectionMode''  none | single | multiple

''grid.value'' or ''grid.value.defaultValue'' contains an array of selected row id

''grid.rowStyle.selected''

''grid.columns[*].style.selected'' allows users to style cells separately for row selected state

''grid.columns[*].style.hover'' allows users to style cells separately for row hover state

''grid.columns/checkboxColumn.gridSelectionSync'' enables synchronization between the state of a //Check Box// control and //row selection//

Getting an array of selected rows from the visual control:

<sxh DSQL; gutter: true;>
  var rrows = dataGrid.getSelectedRows();
  console.log('Selected Rows: ', rrows);
</sxh>  



\\
\\