You've mastered server-side code inside of Aras Innovator and know the IOM like the back of your hand. Now there's just one obstacle left to tackle as an Aras developer: JavaScript. Unlike the nice predictability of server-side code where every method must accept and return an Item object, JavaScript methods are more fluid, and the arguments passed into them can change depending on where the method is called from. In this blog post, we'll tackle the basics of client-side code and offer some pointers to make your JavaScript code just as reliable as your server-side code.

Getting Started

The biggest benefit to client-side development is that debugging is much more accessible and easy to use as it can all be done directly in the browser. Most of what I know about JavaScript development has come from spending time debugging into and stepping through client-side code. Because the context of JavaScript methods can change so much, using the developer tools can be one of the most effective ways to see what information you have access to for any given method.

The aras Object

Before we get into the meat of this blog post, let's briefly cover a powerful tool we have at our disposal in client-side methods within Aras Innovator: the aras object. In our debugging blog post, we were able to find a function for downloading a file by looking inside this object. This is a catch-all container for much of the common client-side actions that can be performed within Aras Innovator. Actions the user usually performs like opening a tab or creating a new item have corresponding functions inside of the aras object that can be used to accomplish the same things programmatically.

Getting the Necessary Information

As mentioned before, server-side methods always accept and return an Item object. Thus, when writing server-side methods, we usually only have to worry about writing the actual logic and not fetching information. Even when we have to fetch additional data, we can easily do that through the IOM. In client-side development though, finding the information we need is half the challenge.

As usual, it's good to base the approach we take on existing code. In the Product Engineering (PE) application, there's a method called PE_GetSelectedItems that gathers all of the items in the main search grid and passes them as a collection to an entirely separate method, so that the other method only needs to be evaluated once regardless of how many items are selected in the grid. Depending on our exact use case, you might find it useful to take this approach of splitting up the way you get the information you're looking for and your actual logic into two separate methods. This can save you from having a lot of duplicate code if you find yourself looking up information in the same way multiple times.

Ways to Retrieve Information

There are a number of ways to get the information we need to run our client-side logic.

Get Input from the User

There's one key thing we only have access to in client-side code: the user. For some actions, we may want to prompt the user to provide some additional information, or we may just want to build a custom UI that lets the user perform many different actions. Regardless, to get input from the user, we can bring up a dialog to prompt the user to perform some action. 

Get Info from the Window

Server-side methods are always run in the context of an Item which can be accessed through a variable called this. Client-side methods on the other hand are run in the context of the Window the user is currently looking at and thus can change. There are a few different variables and places where context information is commonly stored. 

  • inDom is a variable used in quite a few client-side methods that stores the item context if appropriate
  • inArgs is a variable used to store additional information
  • document.thisItem can be used to look up the context item if inDom is empty

If you know the piece of information you're looking for exists in the window but isn't accessible through any of the above variables, it's also possible to dig a little deeper in the path of the window to get what you're looking for. For example, if we're in the context of an Item form and we want to get which relationship tab is currently selected, we can use code like the sample below.

var relationshipTabInfo = parent.relationships.relTabbar;
var currentRelationshipTabId = relationshipTabInfo.GetSelectedTab();
var tabLabel = relationshipTabInfo.GetTabLabel(currentRelationshipTabId);

Query for Item Data

When the info we need for our logic isn't on the page at all, we can always rely on querying the database for any additional information. While there are a few different ways to do this, the easiest way is to just use something we're already familiar with like the IOM. Thankfully, a client-side copy of the IOM exists and is easily accessible through the aras object that we covered up above. You can see an example of using this client-side IOM below.

let item = aras.IomInnovator.newItem("Part", "get");
item = item.apply();

Calling Other Methods From JavaScript

If we're following the convention of having one method retrieve the information we need and one method to actually perform the logic, then we need some way of calling another method from our JavaScript code. There are a couple ways to do this depending on what type of method we want to call.

Server Method

Our way of calling a server method is very similar to that of querying for data. We can use the same aras.IomInnovator object to access the IOM, and then we can simply pass in the name of our server method as the action of our query.

var myMethod = aras.IomInnovator.newItem("Part", "myCustomMethod");
var res = myMethod.apply();

Client Method

The way of calling a client method is a little different but still goes through the aras object. Instead, we can use aras.evalMethod and pass in the name of our JavaScript method. This method also takes in two additional arguments which will become the inDom and inArgs variables respectively. The second argument for inDom can be used to pass in the XML of any item data you may want to use in your second method. The third argument for inArgs can be used to pass in any extra data you may want to use in your second method.

var myMethodName = "myCustomJSMethod";
var myItemInfo = "<Item type='Part'></Item>";
var myAdditionalArguments = {
    arg1: 1,
    arg2: 2
};

aras.evalMethod(myMethodName, /* inDom */myItemInfo, /* inArgs */myAdditionalArguments);

Conclusion

Client-side development is a big topic to cover, so in this blog post, we focused just on some Innovator-specific development tips. Because client-side code is so flexible though, it's also possible to do a number of advanced things like loading in third party libraries, building custom dialogs, etc. What features have you used JavaScript methods for?