Advanced Configuration Options – Single Level Grids

Miscellaneous ››
Parent Previous Next

So far, we have looked at a fairly simplistic example of the power and features of the ReactDataGrid. In this section, let’s review what a real grid looks like in a typical LOB application. This example is a part of the Sample project you get when you request a trial. It is the very first example that you will see on our demo pages as well.

Lets start with a screen shot:

As compared to the earlier simple example grids, you will notice there are a number of additional  features that you will observe.

  1. Left locked columns
  2. Various different kinds of filters
  3. Grouped Columns
  4. The grid appears initially sorted
  5. The text of the Legal Name column is truncated
  6. The alignment of numeric columns is right aligned.
  7. Formatters have been applied to both data and footer fields for the numeric columns
  8. Headers are word wrap enabled

These are all configuration options that are available to you, to save you time, and help you build applications quickly.

Let's look at the markup used to generate this grid.  A lot of this looks quite familiar now that you have gone through the simple examples. But you will notice quite a few new properties, each with their own functionality:

    <ReactDataGrid id={(grid) => {this.grid = grid}} enablePrint={true}  enableExport={true}  

       enablePreferencePersistence={true} preferencePersistenceKey={"simpleGrid"} useCompactPreferences={true}  

       horizontalScrollPolicy={"auto"}  footerDrawTopBorder={true} >

       <ReactDataGridColumnLevel enablePaging={true}  pageSize={50}  enableFilters={true}

           enableFooters={true}  initialSortField={"legalName"}  initialSortAscending={true}>

           <ReactDataGridColumn id={"colId"}  dataField={"id"}  headerText={"ID"}  

               filterControl={TextInput} filterWaterMark={"Search"} selectable={true} filterComparisionType={"number"} />

           <ReactDataGridColumn id={"colLegalName"} dataField={"legalName"}  sortCaseInsensitive={true}  selectable={true}  

               headerText={"LegalName of the Organization"} headerWordWrap={true}  truncateToFit={true}  

               columnLockMode={"left"}  filterComparisionType={"string"} />

           <ReactDataGridColumn id={"colLine2"}  dataField={headquarterAddress.line2} headerText={"Line 2"}

               selectable={true} filterComparisionType={"string"} />

           <ReactDataGridColumnGroup headerText={"Region"} >

               <ReactDataGridColumn id={"colCity"}  dataField={}  headerText={"City"}  

                   filterControl={MultiSelectComboBox}  filterComboBoxWidth={150}  filterComboBoxBuildFromGrid={true}  

                   filterComparisionType={"string"} />

               <ReactDataGridColumn id={"colState"}  dataField={}  headerText={"State"}  

                   filterControl={MultiSelectComboBox}  filterComboBoxWidth={150}  filterComboBoxBuildFromGrid={true}  

                   filterComparisionType={"string"} />

               <ReactDataGridColumn id={"colCountry"}  dataField={}  headerText={"Country"}  

                   filterControl={MultiSelectComboBox}  filterComboBoxWidth={150}  filterComboBoxBuildFromGrid={true}  

                   filterComparisionType={"string"} />


           <ReactDataGridColumnGroup headerText={"Financials"} >

               <ReactDataGridColumn headerAlign={"right"} id={"colAnnRev"} dataField={"annualRevenue"} headerText={"Annual Revenue"}

                   headerWordWrap={true}  textAlign={"right"}   footerLabel={"Avg:"}  footerOperation={"average"}  footerAlign={"center"}  

                   footerOperationPrecision={2} labelFunction={flexiciousNmsp.UIUtils.dataGridFormatCurrencyLabelFunction}

                   filterControl={NumericRangeBox}  sortNumeric={true}  footerFormatter={new flexiciousNmsp.CurrencyFormatter}  

                   paddingRight={10} headerPaddingRight={20}  filterComparisionType={"number"} />

               <ReactDataGridColumn headerAlign={"right"} id={"colNumEmp"} dataField={"numEmployees"}  headerText={"Num Employees"}  

                   headerWordWrap={true} sortNumeric={true} textAlign={"right"}  footerLabel={"Avg:"}  footerOperation={"average"}  

                   footerOperationPrecision={2} labelFunction={flexiciousNmsp.UIUtils.dataGridFormatCurrencyLabelFunction}  

                   headerPaddingRight={20}  filterComparisionType={"number"} />

               <ReactDataGridColumn headerAlign={"right"} id={"colEPS"} dataField={"earningsPerShare"}  headerText={"EPS"}  

                   headerWordWrap={true} sortNumeric={true} textAlign={"right"}  footerLabel={"Avg:"}  footerOperation={"average"}    

                   footerFormatter={flexiciousNmsp.CurrencyFormatter}  labelFunction={flexiciousNmsp.UIUtils.dataGridFormatCurrencyLabelFunction}  

                   headerPaddingRight={20}  filterComparisionType={"number"} />

               <ReactDataGridColumn headerAlign={"right"}  id={"colStockPrice"} dataField={"lastStockPrice"} headerText={"Stock Price"}  

                   headerWordWrap={true} sortNumeric={true} footerFormatter={flexiciousNmsp.CurrencyFormatter} textAlign={"right"} footerLabel={"Avg:"}

                   footerOperation={"average"} footerOperationPrecision={2} headerPaddingRight={20}  filterComparisionType={"number"}

                   labelFunction={flexiciousNmsp.UIUtils.dataGridFormatCurrencyLabelFunction} />




Among the first things you should notice about this markup is the introduction of the “ReactDataGridColumnLevel” tag. We have not yet covered this in detail, but among the most powerful features of the ReactDataGrid product is its support for hierarchical data. We do not display hierarchical data in this example, but the level introduces an important concept that is universal. One of the most important concepts behind the Architecture of the grid arose from the fundamental requirement that it was created for - that is display of Heterogeneous Hierarchical Data (nested DataGrids - or DataGrid inside DataGrid). The notion of nested levels is baked in to the grid via the "columnLevel" property. This is a property of type "FlexDataGridColumnLevel". This grid always has at least one column level. This is also referred to as the top level, or the root level. In flat grids (non hierarchical), this is the only level. But in nested grids, you could have any number of nested levels. The columns collection actually belongs to the columnLevel, and since there is one root level, the columns collection of the grid basically points to the columns collection of this root level.

In this example, we just have 1 level, which is also the top level. In fact, the columns you see in the grid are defined on the level object, not the grid. This is because for nested grids, you could have levels inside levels, each with its own set of columns.

<ReactDataGrid ref={(grid) => {this.grid = grid;}} . . . gridAttributes . . .>


                           <ReactDataGridColumnLevel . . . levelAttributes . . .>

As we will see in a future example, for grids with multiple levels of hierarchy, it is possible to embed levels inside levels. If the number of levels is unknown at the outset, you can also set enableDynamicLevels to true, and the grid will inspect your data provider to figure out the depth needed.

The other important concept here is that of column groups. When you have a large set of columns, it helps to group then inside column groups.  As you can observe, we can also nest column groups within columns groups:

<ReactDataGridColumnGroup headerText="Address" enableExpandCollapse="true" >


                                                           <ReactDataGridColumnGroup headerText="Lines" >

                                                                           <ReactDataGridColumn . . .

Other than these, most of the properties in this markup are fairly self-explanatory. Each of these properties has a description in the API documentation. Please NOTE – since some properties have getters and setters, the documentation will most likely be associated with the corresponding getter OR setter, depending on which is most likely to be used.. For example:


The documentation in this case is associated with labelFunction appears under getLabelFunction:


A function that determines the text to display in this column. By default the column displays the text for the field in the data that matches the column name. However, sometimes you want to display text based on more than one field in the data, or display something that does not have the format that you want. In such a case you specify a callback function usinglabelFunction.

For the DataGrid control, the method signature has the following form:

labelFunction(item:Object, column:DataGridColumn):String

Where item contains the DataGrid item object, and column specifies the DataGrid column.

A callback function might concatenate the firstName and lastName fields in the data, or do some custom formatting on a Date, or convert a number for the month into the string for the month.

The labelFunction also introduces an important concept, that of associating JavaScript callback functions to various APIs of the grid. The string that you pass into the value for this property is usually something that can be evaluated to a named javascript function. As an example: 


This function looks like: 


    * Datagrid function to format the date column in a grid.

    * @return A formatted date string



   UIUtils.dataGridFormatDateLabelFunction = function (item, dgColumn) {

       var num = UIUtils.resolveExpression(item, dgColumn.getDataField());

       var date = typeof num == 'string' ? new Date(Date.parse(num.toString())) : num;

       if (date)

           return UIUtils.formatDate(date);

       return null;


Note that each function that you associate with the string has to have a set contract. This contract is usually defined in the documentation of the property. In this example, the labelFunction has been documented as labelFunction(item:Object, column:DataGridColumn):String, which is what we have done in our UIUtils.dataGridFormatDateLabelFunction function.