[]
        
(Showing Draft Content)

FlexGrid Data-binding

Client-side Data Binding

When you set the grid's itemsSource property to a regular JavaScript array, it automatically creates an internal CollectionView and uses that as a data source so it can provide sorting and editing features without forcing you to create a CollectionView yourself.

This internal view is exposed by the grid's collectionView property, and you can use it to in case you need the extra functionality yourself.

For example, the grid below is bound to a regular array:

import * as wjCore from '@grapecity/wijmo';
import * as wjGrid from '@grapecity/wijmo.grid';

// create some random data
var countries = 'US,Germany,UK,Japan,Italy,Greece'.split(',');
var data = [];
for (var i = 0; i < countries.length; i++) {
  data.push({
    id: i,
    country: countries[i],
    sales: Math.random() * 10000,
    expenses: Math.random() * 5000
  });
}

// bind a grid to the raw data
var theGrid = new wjGrid.FlexGrid('#theGrid', {
    allowSorting: false,
    showSort: false,
    autoGenerateColumns: false,
    columns: [
        { binding: 'country', header: 'Country', width: '2*' },
        { binding: 'sales', header: 'Sales', width: '*', format: 'n2' },
        { binding: 'expenses', header: 'Expenses', width: '*', format: 'n2' }
    ],
    itemsSource: data
});

The grid's collectionView property can be used to sort the data:

  // sort the data by country
var sd = new wjCore.SortDescription('country', true);
theGrid.collectionView.sortDescriptions.push(sd);

Server-Side Data Binding

If the data is on a server, you can retrieve it using the httpRequest method. When you get the response from the server, set the CollectionView's sourceCollection array to the response value or append the new data to the sourceCollection array. Binding FlexGrid (or any control) to this CollectionView will allow it to display any data or changes in the sourceCollection.

import * as wjCore from '@grapecity/wijmo';
import * as wjGrid from '@grapecity/wijmo.grid';

  // create an empty CollectionView and bind a new FlexGrid to it
  var serverView = new wjCore.CollectionView();
  var theGrid = new wjGrid.FlexGrid('#theGrid', {
    allowSorting: false,
    showSort: false,
    isReadOnly: true,
    itemsSource: serverView
  });

  // populate it with data from a server
  var url = 'https://services.odata.org/Northwind/Northwind.svc/Categories';
  var params = {
    $format: 'json',
    $select: 'CategoryID,CategoryName,Description'
  };
  wjCore.httpRequest(url, {
    data: params,
    success: function(xhr) {

      // got the data, assign it to the CollectionView
      var response = JSON.parse(xhr.response);
      var data = response.d ? response.d.results : response.value;

      // use the result as the sourceCollection
      serverView.sourceCollection = data;

      // append results to the sourceCollection
      // in case you want to load data in parts
      //serverView.deferUpdate(function () {
      //  data.forEach(function(item) {
      //		serverView.sourceCollection.push(item);
      //  });
      //});
    }
  });

If your data service API supports commands such as filtering, sorting, and paging, you can add parameters to your httpRequest calls to support those. You can even encapsulate the server API into a custom class that extends CollectionView.

For a simple example of a custom server-based CollectionView class, see our ServerCollectionView sample.

For more complete examples, with full support for CRUD operations, see the Breeze and OData samples or check out the source code for the ODataCollectionView class.

Binding to OData

Wijmo includes an ODataCollectionView class that extends CollectionView to provide support for OData sources.

OData is an OASIS standard that defines a set of best practices for building and consuming RESTful APIs. OData helps you focus on your business logic while building RESTful APIs without having to worry about the various approaches to define request and response headers, status codes, HTTP methods, URL conventions, media types, payload formats, query options, etc.

To use the ODataCollectionView class, create a new instance passing the URL of the data service, the name of the table you want to access, any optional parameters such as the fields you want to retrieve and whether you want filtering, sorting, and paging to be performed on the server or on the client.

If your data source supports writing, make sure to include the key fields as well.

This example shows a list of Northwind customers loaded from a public (read-only) OData source.

The record counter above the grid shows how the data is loaded in batches. This is done by the OData server.

In this example, filtering and sorting are done on the server:

import * as wjOdata from '@grapecity/wijmo.odata';
import * as wjGrid from '@grapecity/wijmo.grid';
import * as wjGridFilter from '@grapecity/wijmo.grid.filter';

// get customer list from Northwind OData service
  var url = 'https://services.odata.org/Northwind/Northwind.svc';
  var customers = new wjOdata.ODataCollectionView(url, 'Customers', {
  	sortOnServer: true,
    filterOnServer: true
  });
  
  // show the data on a grid
	var itemCountElement = document.getElementById('itemCount');
  var theGrid = new wjGrid.FlexGrid('#theGrid', {
  	itemsSource: customers, // ODataCollectionView
  	isReadOnly: true, // this service is read-only
    loadedRows: function() {
    	itemCountElement.innerHTML = theGrid.rows.length + ' items'
    }
  });
  
  // add a filter to the grid
  var f = new wjGridFilter.FlexGridFilter(theGrid);

Binding to Virtual OData

The ODataCollectionView class provides a simple way to connect controls to OData sources. When you create an ODataCollectionView, it starts loading the data in the source.

The ODataVirtualCollectionView extends ODataCollectionView to provide on-demand loading of data. It does not load the data from the server automatically. Instead, it relies on the setWindow method to load data fragments (windows) on demand.

Example:

import * as wjCore from '@grapecity/wijmo';
import * as wjOdata from '@grapecity/wijmo.odata';
import * as wjGrid from '@grapecity/wijmo.grid';

// get order details into an ODataCollectionView
var url = 'https://services.odata.org/Northwind/Northwind.svc';
var table = 'Order_Details_Extendeds';

// get order details into a ODataVirtualCollectionView
var virtualDetails = new wjOdata.ODataVirtualCollectionView(url, table, {
    loaded: function(sender, e) {
        var el = document.getElementById('totalItemCount');
        el.innerHTML = wjCore.format('{totalItemCount:n0} items', sender);
    }
});
  
// show the data on a grid
var theVirtualGrid = new wjGrid.FlexGrid('#theVirtualGrid', {
    itemsSource: virtualDetails, // ODataVirtualCollectionView
    isReadOnly: true, // this service is read-only
    formatItem: function(s, e) { // show row indices in row headers
            if (e.panel.cellType == wjGrid.CellType.RowHeader) {
                e.cell.textContent = e.row + 1;
            }
    },
    scrollPositionChanged: function () {
        var rng = theVirtualGrid.viewRange;
        virtualDetails.setWindow(rng.row, rng.row2);
    }
});