Supply Chain Management in Dynamics AX

This blog contains information and feedback on the Supply Chain Management area in Microsoft Dynamics AX

Customization: how to add an image control on WMDP pages?

Customization: how to add an image control on WMDP pages?

Rate This
  • Comments 5

Warehouse Mobile Devices Portal (WMDP) comes with a number of predefined work pages, dynamic menus, a logon page, and few other screens. The content and the workflow of the pages that are displayed to the user are fully defined on the AOS tier. The X++ classes that belong to the hierarchy inherited from the WHSWorkExecuteDisplay class contain all of the form logic for WMDP. In particular, they are responsible for creating the structure of the logical form, which contains logical controls. The logical form is packaged into XML that is passed to the WMDP running on IIS, and rendered to the html pages that are displayed to the user. The page rendering on the WMDP tier recognizes the following types of logical controls:

  • Text input, rendered as an html “input” element of type “text”
  • Password input, rendered as an html “input” element of type “password”
  • Label element, rendered as an html “label” element
  • Button element, rendered as an html “input” element of type “submit” or “button”
  • Combo box, rendered as an html “select” element
  • Link control, rendered as an html “a” element

These controls are enough to render pages for all of the scenarios that WMDP supports out-of-the-box. However, when you build your own work page or customize an existing one, you may require that the API for building portal pages will add a control type that is not included in the list above.

Question: What if I wanted to add a different kind of control, such as an image?

Answer: Well, ideally you should be able to rely on some sort of extensibility model that would allow you to plug in your own logic that is responsible for rendering your custom control. Unfortunately, the WMDP that shipped with Dynamics AX 2012 R3 does not have any extensibility model for rendering page controls.

I have been approached by a number of people who were not exactly satisfied with that answer. In this short blog post I will describe a workaround that will enable you to add another type of html control without having to modify the sealed binaries of WMDP. We will add an image control to the log on screen. I’ll grant that perhaps this example isn’t terribly exciting, but it’s easy to test because it’s the first screen that is displayed when we restart WMDP after making a change.

To add the image control, the first step is to open and edit the X++ method that is responsible for building the logon screen. Use the following path in the AOT to find the method.

\Classes\WHSWorkExecuteDisplayLogin\buildGetUserIdPassword

Let’s add a line of code that creates a label control with a URL to the image that we want to show on the logon screen:

    ret += [this.buildControl(#RFLabel, 'IMG_01', 'http://localhost/thumbsup.jpg', 1, '', #WHSRFUndefinedDataType, '', 0)];

 The new line of code adds a label control named “IMG_01” with the value of the URL of an image file named thumbsup.jpg. In this case, I want to add this line after the password input control and the logon button. After generating incremental IL and restarting WMDP, the logon screen contains a label with the URL to an image that is available on the localhost.

 

If we open the logon page in IE and go to Developer Tools (F12), we will see the following element within the html structure:

 

As we can see, the label control was rendered as html label element with ID=“IMG_01Lbl”. The “Lbl” suffix was added during the construction of the html page on WMDP. It’s important to be able to assign custom identifiers to html elements. If we ensure uniqueness in global naming, we can design a contract between the client and server that requires that every label element prefixed with particular text has a special meaning. In our case, if we assume that the label element identifier is prefixed by “IMG_”, the label text will be treated as the URL of actual image element that should be added to the page. In order to make the magic happen, we need to add a little bit of JavaScript code to the MVC view file, which we are using for rendering our pages. In particular, we can edit Display.aspx (located under <WMDP instance root>\Views\Execute). Let’s add the following JavaScript function.

function init() {

    var x = document.getElementsByTagName('label');

 

    for (var i = 0; i < x.length; i++) {

        var control = x.item(i);

 

        if (control.id.indexOf('IMG_') == 0) {

            control.style.display='none';

            var picture=document.createElement('img');

            picture.setAttribute('src', control.outerText);

            control.parentNode.appendChild(picture);

        }

    }

}

 

And call it on page load.

 

<body onload="init();">

 

 

If we reopen the logon screen now, we will see that the label element is gone in the HTML and the image control is now added:

 

So, with a very minor change we managed to add an image control to the logon screen. This is fun, but probably not very useful. I believe that this kind of functionality can come in handy when executing actual work, for example, where a user wants to see the image of the item that he or she has been instructed to pick or count in the warehouse.

As for the technical solution, we need to remember that the same MVC view file is used to render logon screen, the menus and all the work pages displayed on the mobile device. With that in mind we need to remember the following:

  • Our naming convention needs to be verified in terms of uniqueness, so that we will not end up trying to render pictures using actual message labels
  • The JavaScript is present on every page we load. Our little function for rendering images is not that heavy, but if you get carried away by your imagination, you may end up with a performance (and maintainability) problem.
  • In this particular case, the URL was originated from a hardcoded string value. You may need to be more careful when dealing with user entered data. Remember to threat model your solutions. WMDP encodes html responses to protect you against XSS attack, but does not perform any validation of the target of the URL that you are passing in the XML.

 

  • Thank you, Pawel!

    This is exactly what we needed for a proof of concept!

    EUgene

  • Thank you!

    Would it be possible to provide a tutorial on how to incorporate product images into the necessary menu locations? Furthermore, can you explain how to use WMDP on a mobile device w/ a barcode scanner?

    Sid

  • Hi  Sid,

    So unfortunately there is no quick way of globally enabling product images across different menu items. I’m afraid that a change of this size is too big to be discussed through a tutorial posted on this blog. This kind of customization would require changes in many places and would need to be handled case by case for each work form.

    But let’s take inventory adjustment for the example, and the WhsWorkExecuteDisplayAdjustIn class. In the buildAdjustIn method you will find the code block that builds extra description controls based on WHSInventTable data. This would typically be the place for injecting inclusion of your product image.

    If you wish to investigate other cases, I suggest to use WHSWorkExecuteForm class for accessing the portal pages from AOT. With that, the pages are rendered using AX forms. Running the portal pages using this class allow you to save time on IL generation and make your debugging experience lighter.

    Regarding your second question, the bar code scanner on the devices behaves like yet another input device. It can scan the bar code and pass it as textual input in a similar way as HID devices do. So if you simply put a keyboard focus on a text box and press the “scan” button, the scanner records the value behind the bars and passes it as a sequence of characters to your text box. This of course works with the installed web browser.

    I hope this answers your questions...

    Pawel

  • Pawel, could you help - how in AX defined company in which user logons through the web-menu?

  • Hi Max,

    I apologize for delayed answer. In order to connect to different companies you need to install multiple instances of WMDP. During installation you will need to specify different Active Directory identity for each instance (each instance uses different IIS application pool, therefore can run under different credentials). Then, after installing, you need to create AX user account for each of the identities used during installation. The default company set on that user account in AX will be the one that particular instance of the WMDP is working with.

    Please see this article for more information:

    technet.microsoft.com/.../dn741429.aspx

    Of course your users will need to work with different URLs. You may want to create shortcuts on devices to make their life easier.

    Pawel

Page 1 of 1 (5 items)
Leave a Comment
  • Please add 1 and 5 and type the answer here:
  • Post