web
You’re offline. This is a read only version of the page.
close
Skip to main content
Community site session details

Community site session details

Session Id :
Supply chain | Supply Chain Management, Commerce
Unanswered

How to add a filter to a custom view similar behaviour as Order fulfillment lines

(0) ShareShare
ReportReport
Posted on by 1,455

I have created a view that does a realtime call to D365 to pull fulfillment lines for a specific itemId and warehouse.

This is all working now.

Now I have to add a filter button on the AppBar. The filter button is calling the dialog box and I can type in a filter value. When I click on the Apply button it does return the value I entered. It also go and retrieve the record for the added filter. e.g. default filter is ItemId and warehouse, I added a salesId to the mix with the filter.

The default filters return 4 lines. I entered the salesId of one of the lines and when stepping trhough the code I can see it retrieved the 1 line. However it is not refreshing the view. How can I get it to refresh the view. Here are my code for the ViewModel:

***

import { ClientEntities } from "PosApi/Entities";
import { ObjectExtensions, StringExtensions } from "PosApi/TypeExtensions";
import { IReservedOrderViewModelOptions } from "../../ViewExtensions/InventoryLookupView/ReservedOrdersViewParameters";
import { ICustomViewControllerContext, ICustomViewControllerBaseState } from "PosApi/Create/Views";
import KnockoutExtensionViewModelBase from "../BaseClasses/TMCKnockoutExtensionViewModelBase";
import { ReservedOrders } from "../../DataServices/DataServiceRequests_ReservedOrders.g";
import { Entities } from "../../DataServices/DataServiceEntities_ReservedOrders.g";
import * as ClientReservedOrders from "../Entities/IReservedOrders";
import ReservedOrdersFilterDialogModule from "../../Controls/Dialogs/ReservedOrdersFilterDialogModule";
import { IReservedOrdersFilterDialogResult } from "../../Controls/Dialogs/IReservedOrdersFilterDialogResult";
import { MessageService } from "../../Controls/Dialogs/MessageBox/MessageBoxService";
/**
 * The ViewModel for Reserved order fulfillment lines.
 */
export default class ReservedOrderLinesViewModel extends KnockoutExtensionViewModelBase {
    public title: Observable<string>;
    public reservedOrderLines: ClientReservedOrders.IReservedOrders[];
    public searchCriteria: Entities.ReservedOrdersSearchCriteria;
    public isPageModeBusy: Observable<boolean>;
    private _context: ICustomViewControllerContext;
    private _options: IReservedOrderViewModelOptions;
    private _customViewControllerBaseState: ICustomViewControllerBaseState;

    constructor(context: ICustomViewControllerContext, state: ICustomViewControllerBaseState,
        options?: IReservedOrderViewModelOptions) {
        super();
        this._context = context;
        this._options = options;
        this.title = ko.observable(StringExtensions.format(
            this._context.resources.getString("tmc_42"), this._options.itemNumber));
        this._customViewControllerBaseState = state;
        this._customViewControllerBaseState.isProcessing = true;
        this.isPageModeBusy = ko.observable(true);
        this.searchCriteria = new Entities.ReservedOrdersSearchCriteria();
        this.searchCriteria.ItemId = this._options.itemNumber;
        this.searchCriteria.WhseId = this._options.InventoryLocationId;
        this.reservedOrderLines = [];
    }   
    public loadAsync(): Promise<void> {
        let getLines: ReservedOrders.TMCGetReservedOrdersActionRequest<ReservedOrders.TMCGetReservedOrdersActionResponse> =
            new ReservedOrders.TMCGetReservedOrdersActionRequest<ReservedOrders.TMCGetReservedOrdersActionResponse>(this.searchCriteria);
            //new ReservedOrders.TMCGetReservedOrdersActionRequest<ReservedOrders.TMCGetReservedOrdersActionResponse>(this._options.itemNumber, this._options.InventoryLocationId);
        // Get current store number
        return this._context.runtime.executeAsync(getLines)
            .then((response: ClientEntities.ICancelableDataResult<ReservedOrders.TMCGetReservedOrdersActionResponse>): void => {
                if (ObjectExtensions.isNullOrUndefined(response)
                    || ObjectExtensions.isNullOrUndefined(response.data)
                    || response.canceled) {
                    return;
                }
                let RRorders:  ClientReservedOrders.IReservedOrders[] = [];
                response.data.result.forEach((fulFillmentLine: Entities.FulfillmentReservedOrders): void => {
                    RRorders.push(fulFillmentLine);
                });
                this.reservedOrderLines = RRorders;
                this._customViewControllerBaseState.isProcessing = false;
            }).catch((reason: any) => {
                this._context.logger.logError("ReservedOrderLinesView: " + JSON.stringify(reason));
                this._customViewControllerBaseState.isProcessing = false;
            });
    }

    public filterOrders(): void {
        let RODialog: ReservedOrdersFilterDialogModule = new ReservedOrdersFilterDialogModule();
        RODialog.open(this.searchCriteria).then((result: IReservedOrdersFilterDialogResult) => {
            if (result.operation == 'Apply') {
                this.searchCriteria = result.result;
                this.searchCriteria.ItemId = this._options.itemNumber;
                this.searchCriteria.WhseId = this._options.InventoryLocationId;
                this.loadAsync();
            }
        });
    }
}

***

Method filterOrders() are being called by the appBar filter button:

***

let config: Views.ICustomViewControllerConfiguration = {
            title: "Filter",
            commandBar: {
                commands: [
                    {
                        name: "ROView_appBarCommand",
                        label: "Filter",
                        icon: Views.Icons.Filter,
                        isVisible: true,
                        canExecute: true,
                        execute: (args: Views.CustomViewControllerExecuteCommandArgs): void => {
                            this.viewModel.filterOrders();
                        }
                    }
                ]
            }
        };

***

"ReservedOrdersFilterDialogModule" is the dialog that is opened where I entered the extra filter and it does return the value entered. so that part is working.

I first had it that filterOrders() called a separate method that does the same as method loadAsync(), but it also retrieved the qualified record but isn't refreshing the view. Seeing that it is duplicate code, I switched to calling loadAsync().

Any idea how I can refresh the grid in the view? Any help is much appreciated.

I have the same question (0)
  • Retha Profile Picture
    1,455 on at
    RE: How to add a filter to a custom view similar behaviour as Order fulfillment lines

    I got this to work.

    ***

    import { ClientEntities } from "PosApi/Entities";

    import { ObjectExtensions, StringExtensions } from "PosApi/TypeExtensions";

    import { IReservedOrderViewModelOptions } from "../../ViewExtensions/InventoryLookupView/ReservedOrdersViewParameters";

    import { ICustomViewControllerContext, ICustomViewControllerBaseState } from "PosApi/Create/Views";

    import KnockoutExtensionViewModelBase from "../BaseClasses/TMCKnockoutExtensionViewModelBase";

    import { ReservedOrders } from "../../DataServices/DataServiceRequests_ReservedOrders.g";

    import { Entities } from "../../DataServices/DataServiceEntities_ReservedOrders.g";

    import ReservedOrdersFilterDialogModule from "../../Controls/Dialogs/ReservedOrdersFilterDialogModule";

    import { IReservedOrdersFilterDialogResult } from "../../Controls/Dialogs/IReservedOrdersFilterDialogResult";

    import { MessageService } from "../../Controls/Dialogs/MessageBox/MessageBoxService";

    /**

    * The ViewModel for Reserved order fulfillment lines.

    */

    export default class ReservedOrderLinesViewModel extends KnockoutExtensionViewModelBase {

       public title: Observable<string>;

       //public reservedOrderLines: ClientReservedOrders.IReservedOrders[];

       public reservedOrderLines: ObservableArray<Entities.FulfillmentReservedOrders>;

       public searchCriteria: Entities.ReservedOrdersSearchCriteria;

       public isPageModeBusy: Observable<boolean>;

       private _context: ICustomViewControllerContext;

       private _options: IReservedOrderViewModelOptions;

       private _customViewControllerBaseState: ICustomViewControllerBaseState;

       constructor(context: ICustomViewControllerContext, state: ICustomViewControllerBaseState,

           options?: IReservedOrderViewModelOptions) {

           super();

           this._context = context;

           this._options = options;

           this.title = ko.observable(StringExtensions.format(

               this._context.resources.getString("tmc_42"), this._options.itemNumber, this._options.InventoryLocationId));

           this._customViewControllerBaseState = state;

           this._customViewControllerBaseState.isProcessing = true;

           this.isPageModeBusy = ko.observable(true);

           this.searchCriteria = new Entities.ReservedOrdersSearchCriteria();

           this.searchCriteria.ItemId = this._options.itemNumber;

           this.searchCriteria.WhseId = this._options.InventoryLocationId;

           this.reservedOrderLines = ko.observableArray([]);

           this.searchReservedOrders();

           this._context.logger.logInformational("ReservedOrderLinesViewModel: success");

       }    

       public searchReservedOrders() {

           this.isPageModeBusy(true);

           this._customViewControllerBaseState.isProcessing = true;

           let searchLines: ReservedOrders.TMCGetReservedOrdersActionRequest<ReservedOrders.TMCGetReservedOrdersActionResponse> =

               new ReservedOrders.TMCGetReservedOrdersActionRequest<ReservedOrders.TMCGetReservedOrdersActionResponse>(this.searchCriteria);

           this._context.runtime.executeAsync(searchLines)

               .then((searchResponse: ClientEntities.ICancelableDataResult<ReservedOrders.TMCGetReservedOrdersActionResponse>) => {

                   this.isPageModeBusy(false);

                   this._customViewControllerBaseState.isProcessing = false;

                   if (!searchResponse.canceled) {

                       this.reservedOrderLines(searchResponse.data.result);

                   }

               }).catch((reason: any): void => {

                   this.isPageModeBusy(false);

                   this._customViewControllerBaseState.isProcessing = false;

                   this._context.logger.logError("ReservedOrderLinesView search: " + JSON.stringify(reason));

                   MessageService.ShowMessage(this, this._context.resources.getString("tmc_40"), JSON.stringify(reason));

               });

       }

       public filterOrders(): void {

           let RODialog: ReservedOrdersFilterDialogModule = new ReservedOrdersFilterDialogModule();

           RODialog.open(this.searchCriteria).then((result: IReservedOrdersFilterDialogResult) => {

               if (result.operation == 'Apply') {

                   this.searchCriteria = result.result;

                   this.searchCriteria.ItemId = this._options.itemNumber;

                   this.searchCriteria.WhseId = this._options.InventoryLocationId;

                   this.searchReservedOrders();

               }

           });

       }

    }

    ***

    I also changed the ReservedOrdersView.ts class  to extend my custom TMCKnockoutExtensionViewControllerBase instead of directly CustomViewControllerBase. The TMCknockout class extends the latter. So I moved the OnReady to the knockout controllerbase class.

    And for some reason because it calls a regular method and not a LoadAsync method, it now refreshes the form after the filter. No idea why, but it works. Maybe it is becaus eI moved the OnReady to the knockout controller base class and  is extending from this one for my view, I have no idea.

    So if somebody can explain the logic, so that one can better understand the behaviour of TypeScript or maybe hw POS reads the classes, then it would be great. 

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

Responsible AI policies

As AI tools become more common, we’re introducing a Responsible AI Use…

Abhilash Warrier – Community Spotlight

We are honored to recognize Abhilash Warrier as our Community Spotlight honoree for…

Leaderboard > Supply chain | Supply Chain Management, Commerce

#1
CA Neeraj Kumar Profile Picture

CA Neeraj Kumar 810

#2
André Arnaud de Calavon Profile Picture

André Arnaud de Cal... 243 Super User 2025 Season 2

#3
Sagar Suman Profile Picture

Sagar Suman 217 Super User 2025 Season 2

Last 30 days Overall leaderboard

Featured topics

Product updates

Dynamics 365 release plans