If there is need to lookup data for a field in the header/filter on a page, you can add a search function.

This is relevant for versions of Mobile WMS for Dynamics 365FO and AX version 3.10 and above

In this article we will take a field in a page header, and add a search capability to it:

  1. Add search capability to a field.
  2. Handle the search request in code


A header/filter on a Mobile WMS App Page is defined in the code in the Mobile WMS classes in AX/365FO.


One example of a filter defined in AX/365FO is taken from the Mobile WMS standard class MobDocProductionOrders


Filter/header definition for Production Order Page
/// <summary>
/// Method to add Report As Finished Header reference data.
/// </summary>
/// <returns>The Report as finished filter fields in an XML formatted string.</returns>
[MobReferenceDataMethod]
public MobReferenceDataConfiguration ReportAsFinishedHeader()
{
    MobReferenceDataConfiguration	conf = new MobReferenceDataConfiguration();
    MobRegistrationCollectorText	prodId = MobRegistrationCollector::collectorFromEDT(extendedTypeStr(ProdId));

    conf.addCollector(prodId);

    return conf;
}


This method gives the following filter, where you can enter a production ID and filter the screen accordingly:


Adding search capabilities

If we go back to the header definition code, we want to enable the field for search. This is done on the MobRegistrationCollector object:

Adding search capability
/// <summary>
/// Method to add Report As Finished Header reference data.
/// </summary>
/// <returns>The Report as finished filter fields in an XML formatted string.</returns>
[MobReferenceDataMethod]
public MobReferenceDataConfiguration ReportAsFinishedHeader()
{
    MobReferenceDataConfiguration	conf = new MobReferenceDataConfiguration();
	MobRegistrationCollectorText	prodId = MobRegistrationCollector::collectorFromEDT(extendedTypeStr(ProdId));

    prodId.parmSearchType("ProdSearch");
 
    conf.addCollector(prodId);
    return conf;        
}


We have added the the usage of the parmSearchType(...) method, which, once it is set, enables the search functionality on the device:

Notice the search icon that have popped up on the device.

But once you click it, you come to a new page, where you can not search for anything, as you can not enter a searchphrase:


To enable the searching we need to add an additional method to the Document Class (MobDocProductionOrders):

Method to add searchfield on the search page
[MobReferenceDataMethod]
public MobReferenceDataConfiguration ProdSearchHeaderConf()
{
    MobReferenceDataConfiguration	conf = new MobReferenceDataConfiguration();
    MobRegistrationCollectorText	prodSearch = new MobRegistrationCollectorText(1,MobConstants::SearchValue(),"Search String","Search String","Search String");
    prodSearch.parmLength(100);

    conf.addCollector(prodSearch);

    return conf;
}

Things to notice in this method:

  • The MobReferenceDataMethod attribute must be set for the method, to make this visible in the Mobile WMS app.
  • The naming of the method must be the string entered as searchType postfixed with "HeaderConf" in this case "ProdSearchHeaderConf"
    • This will ensure the system automatically connect these with each other.

Once this code has been added, the search page will look like this:

From here, once a user enters a value here, the a search request is sent to the AX/D365FO


Handling search request in code

To handle the search request the class MobSearchService needs to be customized or extended, depending on your ERP version.


The method to extend or customize is named doSearch(str _type)

The _type parameter will contain the name defined in searchType, in our case "ProdSearch"

A class variable named searchValue contains the searchphrase the user has entered in the Mobile WMS search page.

An extension method to do search could look like this, to enable search for productions.

Search extension for finding production order based on a search string
protected void doSearch(Str _type)
{
    ProdTable prodTable;
 	int			i;

    if (_type != "ProdSearch")
    {
		//Not the droid you're looking for
        return;
    }
    while select prodTable where 
		(prodTable.ItemId like searchValue ||			
		prodTable.ProdId like searchValue)
	{
        this.addResult(prodTable.ProdId, prodTable.ProdId, prodTable,strFmt('%1: %2', "Production", prodTable.ProdId), prodTable.ItemId, prodTable.itemName);
		i++;
	}
 	if (!i)
    {
        searchValue = '*'+searchValue + '*';
        while select prodTable where
         	(prodTable.ItemId like searchValue ||
            prodTable.ProdId like searchValue)
        {
            this.addResult(prodTable.ProdId, prodTable.ProdId, prodTable,strFmt('%1: %2', "Production", prodTable.ProdId), prodTable.ItemId, prodTable.itemName());
            i++;
        }
    }
}


In the above example, we jump out, if the type is not of "ProdSearch", and proceeds to find all records where either the Production Id or the Item Id matches that of the searchphrase, and returns each records within this criteria. If none are found with the initial searchphrase, the search is widened with an asterisk (*)

The result will look like this in the app:


You can read further on the searchType usage in the app here: SearchType