Easy filtering, paging, and sorting with the retrievalManager class

In the 2.2 release of the Mvc Controls Toolkit we factored out all this “manual” jobs into the new mvcct.retrievalManager javascript class. Now all we need to do is just intercepting all events triggered by the Mvc Controls Toolkit filtering, sorting, and paging controls, and passing their data to the event method of the mvcct.retrievalManager instance we have created. This event can be intercepted by attaching an event handler in a any html node that contains all interested Mvc Controls Toolkit filtering, sorting, and paging controls inside it.

In order to use a retrievalManager we have to add an event handler for the queryChanged event, to an Html node that is an ancestor of all controls that may trigger query related events, that is client pagers and enableSortingFor. The event object passed to the event handler has a type property that specifies the operation to be added to the current query, plus other properties that depend on the type. The types supported are: 

  • "page", something changed in a pager. The event object contains all details. Automatically issued by clients pagers.
  • "sort", the required sorting changed. The event object contains all details. Automatically issued by enableSortingFor controls.
  • "filter", filter conditions changed. There is no control that triggers a "filter" event, therefore this event must be triggered somehow by the developer (typically by using a button). The event object must contain just the property named filterPrefix whose value must be the field prefix of all filtering controls created through DataFilterClauseFor helpers.
  • "refresh", issues again the last query. No control triggers automatically this event, so it must be triggered by the developer (typically by using a button).
  • "custom", enables the developer to add the handling of custom events.


For a quick start on the retrievalManager, and to understand how it operates please refer to this tutorial.

The retrieval manager has the following methods:

  • event(args). Where args is the data object contained in any queryChanged event. This way the retrievalMnager is informed about all changes in the query being built by the user.
  • submit(args). As default a new ajax request is issued to the server each time the event method is called. However, this default behaviour can be overriden when the retrievalManager is created. When this is the case, the request to the server is issued manually by calling the submit method, where args  must be the same argument passed to the last call to event
  • changePageSize(newSize). Use it to change the initila page size passed  at the creation of the retrievalManager.
  • newCache(size). A new cache object is created. It will be used to cache automatically the last size results returned by the server, indexed by the query parameters. If a result is found in the cache it is used instead of issuing the query to the server.
  • getCache(). It returns the cache currently used by the retrievalManager, if any, otherwise null.
  • invalidateCurrentCache(). Invalidate the cache key of the current query, so that next time the query will be issued to the server. Use this method either if you modified the items returned by the last query, or if for some reason you know they changed on the server.
  • options(o). A new options object o is passed to the retrievalManager. Just the options provided in the new object are changed.
  • optionsSetting(propertyName): it returns the current value of the option propertyName.
  • entitiesContainer(): it returns the current entityContainer.
  • declareCustomEventHandler(func): Declares a custom event handler. The custom event handler is invoked each time the retrievalManager receives an event of type "custom". func is invoked with the following parameters: 
    • the retrievalManager.
    • the whole event object received
    • the retrievalManager, main jQueryable
    • the observable containing the current page

A new instance of the retrievalManager can be created by calling:

mvcct.retrievalManager(queryable, pageObservable, pageCountObservable=null, options=null).


  • queryableis the jQueryable object to be used to issue the queries.
  •  pageObservable is the observable that contains the current page number
  •  pageCountObservable is the observable that contains the total number of pages. It can be also null.
  • options is an options object.

The available options are:

  • pageSize, contains the desired page size. This value can be changed at a later time by calling the changePageSize(newPageSize) method.
  • entitiesContainer, contains the observable where to put the array of objects returned by the server.
  • updatesManager, contains the updatesManager that handles the updates of the same array of objects, if any. If no update is needed, there is no need to pass this argument.
  • jFormsToClear, when specified is a jQuery object that contains some forms to clear from previous errors after having received new data from the server(once new data arrive, orld errors become obsolete).
  • onError, contains the function to execute in case of errors. It accepts 4 arguments: args, x1, x2, x3. args contains the data of the queryChanged event that triggered the request to the server, while x1, x2, x3 are the arguments passed to the error function of the ajax jQuery method.The default implementation just display the status code, or a custom message in the validation summary.
  • htmlStatusMessages: a function that is called by the default onError function in case the ajax call to the server returns an error. It is passed the Html statusCode as first argument and the associated statusText as second argument. It is expected to return the error message to display to the user. The default implementation returns the statusText.
  • onAfterError: A function called by the default onError function immediately after it displays the error message. It is passd exactly the same arguments of the onError function. Its default implementation do nothing. A call to a routine that unblocks the UI after the update may be placed here and in the onAfterSuccess function.
  • onSuccess, if specified, overrides the standard model update behaviour of the retrievalManager. It accepts 4 arguments: args, x1, x2, x3args contains the data of the queryChanged event that triggered the request to the server, while x1, x2, x3 are the arguments passed to the success function of the ajax jQuery method.
  • We can also keep the standard model update behaviour of the retrievalManager while simultaneously executing some custom code after the model has been updated, by specifying the onAfterSuccess function that accepts the same arguments of the onSuccess function. 
  • If we use the default onSuccess we can specify alsoa dataTransform function that is passed all items returned by the server, as javascript objects before their properties are turned into ko observables. It is expected to apply a transformation to this data, and then return the array of transformed items.
  • onSubmit, if specified is executed before submitting the request to the server. It accepts two arguments: args, data. args give us the opportunity to cancel the request to the server, by setting args.cancel=true. data is the object we can provide in the data property of the option object.
  • immediateSubmit, has a default value of true. This means that each time a new event is passed to the retrievalManager a new request to the server is issuedIf we set this property to false, the request to the server(with the query by processing  all events received so far) is issued manually by calling the submit() method of the retrievalManager.
  • resultsField and countField have respectively default values "Results" and "TotalCount". They are not used if the server returns just an array of objects, but they are used just if the server returns also the total count of the objects satisfying the query(information needed to improve the paging experience). In this case they specify the name of the properties containing the results and the total count. As default ApiControllers doesnt return the total count, but it is quite easy to write an action filter to add this value. Complete oData sources, return the total count if the query requires it. 
  • pageObservable, if provided, it must be an observable that contains aun user-modifiable page-size.  Once this observable is passed to the retrievalManager, page size changes are automatically handled by the retrievalManager.
  • auxLocal & finalContainer, if provided must be rexpectively a localQueryable, and an observable array. In this case, the entityContainer is used as input array for the localQueryable and all sort commands are issued both to the main jQueryable handled by the retrievalManager and to auxLocal. The result of executing the auxLocal query on entityContainer is returned into  finalContainer. Moreover a knockout dependency is created between entityContainer and  finalContainer. As a result if we modify  entityContainer by adding new entities or by mofifying existing entities, finalContainer automatically updates finalContainer with an array containing the same elements of entityContainer but sorted with the same sorting we used to retrieve the data from the server. 

Last edited Jun 22, 2014 at 10:44 AM by frankabbruzzese, version 7


No comments yet.