
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:
***
***
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 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.