There are two distinct mechanisms you can use to build the grid. XML, and API. The XML is easier, less verbose and can be used to cleanly separate the markup of the grid from the logic associated with it (like event handlers and function callbacks we discuss elsewhere in this guide).
The key to keep in mind however, is that the XML is ultimately passed into helper functions which then call the API methods and build out the grid. So the API is used in both cases, the XML is just a shorthand preprocessor for the API that makes it easier to configure the grid.
XML configuration
When you define a grid, you pass in XML configuration for the grid. We have seen many examples of this so far, but lets look at a simple example here:
$(document).ready(function () {
var grid = new flexiciousNmsp.FlexDataGrid(document.getElementById("gridContainer"),
{
configuration: '<grid id="grid" enablePrint="true" enablePreferencePersistence="true" enableExport="true" forcePagerRow="true" pageSize="50" enableFilters="true" enableFooters="true" enablePaging="true">' +
' <level>' +
' <columns>' +
' <column type="checkbox"/>'+
' <column dataField="id" headerText="ID" filterControl="DynamicFilterControl" footerLabel="Sum: " footerOperation="sum" footerOperationPrecision="2"/>' +
' <column dataField="type" headerText="Type" filterControl="TextInput" filterOperation="Contains" />' +
' </columns>' +
' </level>' +
' ' +
' </grid>',
dataProvider: [
{ "id": "5001", "type": "None", "active": true },
{ "id": "5002", "type": "Glazed", "active": true },
{ "id": "5005", "type": "Sugar", "active": true },
{ "id": "5007", "type": "Powdered Sugar", "active": false },
{ "id": "5006", "type": "Chocolate with Sprinkles", "active": true },
{ "id": "5003", "type": "Chocolate", "active": false },
{ "id": "5004", "type": "Maple", "active": true }
]
});
});
As you see above, we basically pass in an XML string to the constructor of the FlexDataGrid class. One very frequent question comes up is, "What are the various attributes you can specify in XML"?
The answer is simple. All of them. Each and every property mentioned in the documentation can be specified via XML. This includes both properties explicitly exposed as public attributes (e.g. enablePrint, enableExport etc) , and some that are exposed via setters (e.g. setPagerRowHeight, setPagerVisible) . The XML parser is smart enough to figure out if there is a setter with the naming convention setXXXX and use it instead of a direct value set on the property. (This is in red because it often causes confusion among our customers). So pageSize="50" automatically translates to setPageSize(50), even if there is no property called pageSize on FlexDataGrid, but because there is a method named setPageSize. It is also smart enough to figure out that a value is a number passed in as a string, so it will do that conversion as well.
In addition to the above, the XML builder does a lot of preprocessing of the string values passed into it. These steps are described below.
1. Any attribute that matches the name of an event. The XML parser assumes that any string passed in as the value for an event is a function call back and treats it as such. For example creationComplete="myCompanyNameSpace.onCreationComplete". So this needs to evaluate to a name spaced function. A full list of events is available here: http://htmltreegrid.com/docs/classes/flexiciousNmsp.FlexDataGrid.html (events tab)
2. For any properties with the following suffix, we eval the passed in value. This means the value needs to evaluate to a namepace qualified function. e.g. filterRenderer="flexiciousNmsp.DynamicFilterControl":
1. Function
2. Renderer
3. Editor
4. Formatter
5. DateRangeOptions
3. For the following properties, we wrap the value in a ClassFactory:
1. filterRenderer
2. footerRenderer
3. headerRenderer
4. pagerRenderer
5. itemRenderer
6. nextLevelRenderer
7. itemEditor
4. If any value is passed in within curly braces {}, we assume that is a function call. Like {executeFunction(1,2)}. We will execute the executeFunction passing in 1 and 2, and return with the result. This is very rarely used.
5. For any value you prefix with the word eval__, we evaluate it before it gets applied
6. For any value you specify within square brackets [], we assume it is an array, and split the string by commas and convert it to an array.
7. For any value that starts with 0x, we assume its a hex code and use it as such. This is used for colors.
8. For any value that is composed solely of numbers, we parse it as such.
9. Finally, after all this preprocessing is done, we check to see if there is a setter method specified for the property name at the target object level (FlexDataGrid, FlexDataGridColumnLevel, or FlexDataGridColumn). If so, we call the setter method with the preprocessed value. Else, we set a property with that name to the preprocessed value.
1. For the grid tag, you can specify any of the properties listed here : http://htmltreegrid.com/docs/classes/flexiciousNmsp.FlexDataGrid.html
2. For the level tag, you can specify any of the properties listed here : http://htmltreegrid.com/docs/classes/flexiciousNmsp.FlexDataGrid.html
3. For the column tag, you can specify any of the properties listed here : http://htmltreegrid.com/docs/classes/flexiciousNmsp.FlexDataGridColumn.html
API configuration
The API method is basically what the XML configuration method uses. Many of our customers store their grid configuration in the backend. They then use it to build out the grid. Some of them choose to build out XML from their backend and then call the buildFromXML method on the grid. Others build out the grid using the API directly. This gives you more flexibility, but makes the code a lot more verbose. Let's take a quick look at the code required to build out a grid with no XML.
myCompanyNameSpace.DynamicColumns_grid_creationCompleteHandler=function(evt)
{
var grid=this;
grid.setDataProvider(myCompanyNameSpace.FlexiciousMockGenerator.instance().getFlatOrgList());;
grid.clearColumns();
var col=myCompanyNameSpace.DynamicColumns_addColumn("id","Company ID");
col.setColumnLockMode(flexiciousNmsp.FlexDataGridColumn.LOCK_MODE_LEFT)
grid.addColumn(col);
col=myCompanyNameSpace.DynamicColumns_addColumn("legalName","Company Name");
col.setColumnLockMode(flexiciousNmsp.FlexDataGridColumn.LOCK_MODE_RIGHT)
grid.addColumn(col);
grid.addColumn(myCompanyNameSpace.DynamicColumns_addColumn("headquarterAddress.line1","Address Line 1"));
grid.addColumn(myCompanyNameSpace.DynamicColumns_addColumn("headquarterAddress.line2","Address Line2"));
grid.addColumn(myCompanyNameSpace.DynamicColumns_addCurrencyColumn("earningsPerShare","EPS"));
grid.addColumn(myCompanyNameSpace.DynamicColumns_addColumn("headquarterAddress.line1","Address Line 1"));
grid.addColumn(myCompanyNameSpace.DynamicColumns_addColumn("headquarterAddress.line2","Address Line2"));
grid.addColumn(myCompanyNameSpace.DynamicColumns_addCurrencyColumn("earningsPerShare","EPS"));
grid.addColumn(myCompanyNameSpace.DynamicColumns_addColumn("headquarterAddress.line1","Address Line 1"));
grid.addColumn(myCompanyNameSpace.DynamicColumns_addColumn("headquarterAddress.line2","Address Line2"));
grid.addColumn(myCompanyNameSpace.DynamicColumns_addCurrencyColumn("earningsPerShare","EPS"));
grid.addColumn(myCompanyNameSpace.DynamicColumns_addColumn("headquarterAddress.line1","Address Line 1"));
grid.addColumn(myCompanyNameSpace.DynamicColumns_addColumn("headquarterAddress.line2","Address Line2"));
grid.addColumn(myCompanyNameSpace.DynamicColumns_addCurrencyColumn("earningsPerShare","EPS"));
//grid.distributeColumnWidthsEqually();
grid.reDraw();
};
myCompanyNameSpace.DynamicColumnsCounter=0;
myCompanyNameSpace.DynamicColumns_addCurrencyColumn=function(dataField,headerText){
var dgCol = myCompanyNameSpace.DynamicColumns_addColumn(dataField,headerText);
dgCol.setLabelFunction(flexiciousNmsp.UIUtils.dataGridFormatCurrencyLabelFunction);
dgCol.setStyle("textAlign","right");
dgCol.setUniqueIdentifier(headerText+myCompanyNameSpace.DynamicColumnsCounter++);
dgCol.footerOperation="average";
dgCol.footerLabel="Avg: ";
dgCol.footerAlign="right";
dgCol.setStyle("paddingRight",15);
dgCol.filterOperation="GreaterThan";
dgCol.filterWaterMark = "Greater Than";
return dgCol;
};
myCompanyNameSpace.DynamicColumns_counter=0;
myCompanyNameSpace.DynamicColumns_addColumn=function(dataField,headerText){
var dgCol = new flexiciousNmsp.FlexDataGridColumn();
dgCol.setDataField(dataField);
dgCol.setHeaderText(headerText);
//because columns are having the same header text, we need to provide unique identifiers.
dgCol.setUniqueIdentifier(headerText+""+myCompanyNameSpace.DynamicColumns_counter++);
dgCol.filterControl="TextInput";
dgCol.filterOperation="BeginsWith";
dgCol.filterWaterMark = "Begins With";
return dgCol;
};
myCompanyNameSpace.SAMPLE_CONFIGS["DynamicColumns"]='<grid horizontalScrollPolicy="on" id="grid" width="800" height="500" enablePrint="true" ' +
'enablePreferencePersistence="true" generateColumns="false" '+
' enableExport="true" enableCopy="true" enableFilters="true" enableFooters="true" enablePaging="true" ' +
'preferencePersistenceKey="dynamicColumns"'+
' on'+flexiciousNmsp.Constants.EVENT_CREATION_COMPLETE+'="myCompanyNameSpace.DynamicColumns_grid_creationCompleteHandler">'+
' '+
' </grid>';
So, in this example, we just use the XML to initialize the grid. We use API to generate the actual columns. For a running copy of this example, please refer to http://www.htmltreegrid.com/demo/prod_ext_treegrid.html?example=Dynamic%20Columns
We also have a more complicated grid, with column groups and inner levels. The code for this as well as a running example is available here:
http://www.htmltreegrid.com/demo/prod_ext_treegrid.html?example=Large%20Dynamic%20Grid