Skip to content

OData plugin for jqGrid

Mark Babayev edited this page Jun 19, 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 2 formats (see useXmlSerializer):

    <ArrayOfClientModel>
      <ClientModel>
        ...
      </ClientModel>
    </ArrayOfClientModel>
    <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 () {
        $("#grid").jqGrid('odataGenColModel', {...});
      }
    });

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

Arguments:

       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)
       entityType: null                - required field, odata entityType name
       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:

       jqGridODataParseMetadata        - the same as parsemetadatafunc
       jqGridODataParseColumns         - the same as parsecolfunc

Function odataInit

    $("#grid").jqGrid({
      beforeInitGrid: function () {
        $("#grid").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:

       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
       useXmlSerializer: true          - use XmlSerializer as default serializer for XML data
       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: {                   - http verbs for odata and their corresponding actions in jqgrid (this feature requires thorough testing)
           inlineEditingAdd: 'POST',
           inlineEditingEdit: 'PATCH',
           formEditingAdd: 'POST',
           formEditingEdit: 'PUT'
       }

odata colModel parameters

   odataunformat: function (searchField, searchString, searchOper) - works analogous to xmlmap/jsonmap,
                          for example the function body can be: { return searchString !== '-1' ? 'cltype/Id' : null; }
   odataexpand: (link|json|subgrid*) - defines data expansion types for complex and navigation properties,
                          it works only with custom formatters specified in odata cmTemplates.
      link - the link to the property is displayed
      json - the property data is displayed in a json string form
      subgrid - jquery subgrid is opened when clicking on a link inside column (this feature is not available yet).

odata column templates (cmTemplate)

     odataComplexType                  - column template for odata Complex type.
     odataNavigationProperty           - column template for odata Navigation property.

Examples

    $("#grid").jqGrid({
        ...,
        beforeInitGrid: function () {
            $(this).jqGrid('odataInit', {
               annotations: false,
               metadatatype: 'xml',
               datatype: 'jsonp',
               version: 4,
               gencolumns: true,
               expandable: 'json',
               entityType: 'Product',
               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;
                   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,
                entityType: 'ClientModel',
                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,
                useXmlSerializer: false,
                entityType: 'ClientModel',
                odataurl: 'http://localhost:56216/odata/ODClient',
                metadataurl: 'http://localhost:56216/odata/$metadata'
            });
        }
    });