Skip to content

OData plugin for jqGrid

Mark Babayev edited this page Jul 4, 2015 · 15 revisions

This plugin queries odata $metadata service and automatically generates jqGrid columns. It is the easiest way for implementing tables with basic CRUD operations, almost no code is required. In addition to simple column types this plugin supports odata ComplexTypes as well as odata NavigationProperties. Both data and metadata can be provided as json or atom+xml. Atom+xml data can be received in this format:

<feed>
  <entry>
    <link>...</link>
    <content>
       <properties>...</<properties>
    </content>
  </entry>
</feed>

When data is provided in json format the jqGrid parameters like records, page, total, userdata can be obtained via odata annotations. Annotation object name is defined in annotationName: "@jqgrid.GridModelAnnotate"

Function odataGenColModel

$("#grid").jqGrid({
  beforeInitGrid: function () {
    $(this).jqGrid('odataGenColModel', {...});
  }
});

This function generates jqGrid style columns by requesting odata $metadata. It is called by odataInit when gencolumns: true.

Arguments:

Name: default value Description
metadatatype: 'xml' ajax dataType, can be 'json', 'jsonp' or 'xml'(atom)
async: false set ajax sync/async for $metadata request (when calling from odataInit only async=false is supported)
entitySet: null required field, the name of the odata EntitySet
expandable: (link | json | subgrid*) the expansion type for ComplexTypes and NavigationProperties, for details see "odata colModel parameters".
metadataurl: (odataurl || p.url) + '/$metadata' set ajax url for $metadata request
successfunc: null odataGenColModel callback to see when metadata request is over and jqGrid can be refreshed
parsecolfunc: null event for converting parsed metadata data array in form of {name,type,nullable,iskey} to the jqGrid colModel array
parsemetadatafunc: null event for converting unparsed metadata data (xml or json) to the jqGrid colModel array
errorfunc: null error callback

Events:

Event name Description
jqGridODataParseMetadata the same as parsemetadatafunc
jqGridODataParseColumns the same as parsecolfunc

Function odataInit

$("#grid").jqGrid({
  beforeInitGrid: function () {
    $(this).jqGrid('odataInit', {...});
  }
});

This is the main plugin entry point function. It should be called before the colModel is initialized. When columns are defined manually it can be called from events beforeInitGrid or onInitGrid. When columns are created automatically it can be called from event beforeInitGrid only.
Even when gencolumns: true we can still add column definitions manually (colModel: colModelDefinition). Thus columns generated by $metadata will be overwritten by manual definitions.

Arguments:

Name: default value Description
gencolumns: false automatically generate columns from odata $metadata (calls odataGenColModel)
odataurl: p.url required field, main odata url
datatype: 'json' ajax dataType, can be json, jsonp or xml(atom)
entityType: null required field, odata entityType name
annotations: false use odata annotations for getting jqgrid parameters: page,records,count,total
annotationName: "@jqgrid.GridModelAnnotate" odata annotations class and namespace
version odata version (3/4), used to set $count=true or $inlinecount=allpages
errorfunc: null error callback
metadatatype: datatype || 'xml' when gencolumns=true, alternative ajax dataType for $metadata request
odataverbs: {
    inlineEditingAdd: 'POST',
    inlineEditingEdit: 'PATCH',
    formEditingAdd: 'POST',
    formEditingEdit: 'PUT'
}
http verbs for odata and their corresponding actions in jqgrid (this feature requires thorough testing)

odata colModel properties

Name Description
isnavigation the column type is a NavigationProperty that points to another entity
iscomplex the column type is a ComplexType
iscollection the column is a Collection of entities that can be opened in a new subgrid
nosearch when true, this column is excluded from odata search
unformat: function (searchField, searchString, searchOper) works analogous to xmlmap/jsonmap, for example the function body can be: { return searchString !== '-1' ? 'cltype/Id' : null; }
expand: (link json
link the link to the property is displayed
json the property data is displayed in a json string form
subgrid the subgrid is opened when clicking on a link inside column (this feature is not available yet).

odata column templates (cmTemplate)

Name Description
odataComplexType column template for odata Complex type.
odataNavigationProperty column template for odata Navigation property.
#Custom cmTemplates
Plugin allows setting custom cmTemplates for any odata type
$.jgrid.cmTemplate["Edm.GeographyPoint"] = {
    editable: false,
    formatter: function(cellvalue, options, rowObject) {
        if (!cellvalue && this.p.datatype === 'xml') {
            var xmlvalue = $(rowObject).filter(function() {
                return this.localName.toLowerCase() === options.colModel.name.toLowerCase();
            });
            cellvalue = $.jgrid.odataHelper.convertXmlToJson(xmlvalue[0]);
        }
        if(cellvalue.crs && cellvalue.coordinates) {
           return '<div>{0}</div><div>[{1},{2}]</div>'.format(cellvalue.crs.properties.name, cellvalue.coordinates[0], cellvalue.coordinates[1]);
        }
        return '<div>{0}</div>'.format(cellvalue);
    }
};

Examples

$("#grid").jqGrid({
    ...,
    beforeInitGrid: function () {
        $(this).jqGrid('odataInit', {
           annotations: false,
           metadatatype: 'xml',
           datatype: 'jsonp',
           version: 4,
           gencolumns: true,
           expandable: 'json',
           entitySet: 'Products',
           odataurl: "http://services.odata.org/V4/OData/OData.svc/Products",
           metadataurl: 'http://services.odata.org/V4/OData/OData.svc/$metadata',
           errorfunc: function (jqXHR, parsedError) {
               jqXHR = jqXHR.xhr || jqXHR;
               parsedError = $('#errdialog').html() + parsedError;
               $('#errdialog').html(parsedError).dialog('open');
          });
    }
});
$("#grid").jqGrid({
    colModel: colModelDefinition,
    ...,
    // when columns are defined manually (gencolumns=false) the odataInit call
    // can be also put in onInitGrid event.
    beforeInitGrid: function () {
        $(this).jqGrid('odataInit', {
            version: 3,
            gencolumns: false,
            odataurl: 'http://localhost:56216/odata/ODClient'
        });
    }
});
$("#grid").jqGrid({
    colModel: colModelDefinition,
    ...,
    beforeInitGrid: function () {
        $(this).jqGrid('odataInit', {
            version: 4,
            datatype: 'json',
            annotations: true,
            gencolumns: true,
            entitySet: 'ODClient',
            odataurl: 'http://localhost:56216/odata/ODClient',
            metadataurl: 'http://localhost:56216/odata/$metadata'
        });
    }
});
$("#grid").jqGrid({
    colModel: colModelDefinition,
    ...,
    beforeInitGrid: function () {
        $(this).jqGrid('odataInit', {
            version: 4,
            datatype: 'xml',
            annotations: false,
            gencolumns: true,
            entitySet: 'ODClient',
            odataurl: 'http://localhost:56216/odata/ODClient',
            metadataurl: 'http://localhost:56216/odata/$metadata'
        });
    }
});