Call same client Method from different locations (Action, CUI , Form button)

Hi, I wonder what´s the best way to call the same Client Methods from a different locations. The item that triggers the Method needs different handling based on the event used as trigger. A standard ItemType "Action" Method may work like this:
var inn = this.newInnovator()
var myItem = this; // passed with Action
return aras.AlertError("This is " + this.getProperty("name"));
For a Form button onClick this will work:
var myItem = parent.thisItem; // form call
return aras.AlertError("This is " + myItem.getProperty("name"));
CUI elements seem to need an additional call for the Item
var id;
var topWindow = aras.getMostTopWindowWithAras(window);
if (topWindow.work && topWindow.work.grid) 
{ 
    // in case Method is triggered from Main-Window-
    var workFrame = topWindow.work; 
    id = workFrame.grid.getSelectedID();
} 
else 
{
    // in case Method is triggered from Tearoff Window
    id = thisItem.getID();
}

var myItem = inn.getItemById("/*Itemtype*/", id);
return aras.AlertError("This is " + myItem.getProperty("name"));
Form and Actions can be unified in one Method this way:
var myItem;
if (parent.thisItem === undefined){
    myItem = this; // Action call
}
else 
{
    myItem = parent.thisItem; // form call
}

return aras.AlertError(myItem.getProperty("name"));
But I wonder if it´s possible to extend this construct to CUI elements? Background: I have a few Actions, that I want to move to CUI elements. But I don´t want to change anything adhoc. So I would prefer to have more flexible Methods that I can reuse more easily. Thx! Regards Angela
  • Hi Angela, One idea is to create a Client Method that can take in the context of another Method and pull out the Item based on that context. I created a simple example of this called GetItemFromWindow in a test environment with code like the example below.
    var win = inArgs.contextWindow;
    var itm = null;
    // Get the item based on the context of the method calling this
    if (win) {
    var itm = win.parent.item || this;
    }
    return itm;
    You can then call this Method from any other client method using something like the sample below.
    var methodArgs = {
    contextWindow: window
    }
    var itm = aras.evalMethod("GetItemFromWindow", this.node, methodArgs);
    Assuming that the logic of the GetItemFromWindow Method is sound, you can write context-independent client Methods that can be reused with any location. The code in my sample would need to be updated to include a check for CUI, but this could be a neat Community Project when you get it working! Submitting a new project during Hacktoberfest will earn you some exclusive Aras swag. Chris
    Christopher Gillis Aras Labs Software Engineer
  • Hi Chris, interesting concept! So you use the methodArgs for passing what you want to have returned? Somehow like this? var methodArgs = { contextWindow: window } or var methodArgs = { contextWindow: cui_mwt } or var methodArgs = { contextWindow: cui_twt } I agree, that a sample project that shows the various calls would really be helpful. Is it right that we need the additional getItemById call for the cui buttons? Or is the item somehow located in the workframe?
  • Hi Angela, The sample I wrote is just one possible implementation, but the goal is to make the way you call GetItemFromWindow as generic as possible. window is actually a JavaScript object that can give us information about where the method is being called from, so the methodArgs at least in this sample should always look like  var methodArgs = { contextWindow: window }. The GetItemFromWindow function should then be able to figure out what the context is based on what properties it has access to from the contextWindow. To answer your second question, I don't believe that you have access to the item itself from the context of the cui button, so the getItemById call is necessary. Chris
    Christopher Gillis Aras Labs Software Engineer
  • It´s somehow not so easy to differentiate the CUI elements from the rest. "window" is always present, I don´t know how to use this one for differentiation. The itm sometimes already contains the selected items, sometimes just an Object Element. I tried the following ones: itm.constructor.name == "Element" -> in case when Method is called from a Form (CUI twt + Action) itm.getItemCount(); -> Is -1 for CUI mwt calls and >0 for Action calls. But throws an error for CUI twt elements. Are there additional parameters passed that could be helpful?
  • Hi Angela, You can try passing in the inArgs and/or the inDom into your GetItemFromWindow method. It looks like inArgs.control only exists if the item is called from a CUI button.
    // Call GetItemFromWindow
    var methodArgs = {
    contextWindow: window,
    contextArgs: inArgs,
    contextDom: inDom
    }
    var itm = aras.evalMethod("GetItemFromWindow", this.node, methodArgs);
    Then you can add a check to the start of your GetItemFromWindow method like...
    var win = inArgs.contextWindow;
    var contextArgs = inArgs.contextArgs;
    // The inArgs of the calling method only contain a control if it's from a CUI button
    if (contextArgs && contextArgs.control) {
    // Perform the lookup appropriate of an item from a CUI button
    }
    Chris
    Christopher Gillis Aras Labs Software Engineer
  • Hi Chris, Typical for friday afternoon, I was so focused on the window that I totally ignored the other parameters. I made a first sample package, also it still needs some testing. call-method-from-different-locations I wonder if the currenct code can also work for onClick events called from button in Forms? I made a few tests, but inArgs is not present on Form calls. Angela
  • I know this thread is quite old, but I still like the topic, cause Method calls are an everyday tasks.

    I wonder if the shown calls will still work with Innovator 12. Especially as we now have even more options to use CUI elements.

    One topic is how to deal with CUI dropdowns. Another one the call of Methods from CUI elements that we use in relationships. I so far weren´t able to create a working CUI button in a relationship toolbar or popup menu. I weren´t able to figure out if a custom CUI element will be used in ALL relationships assigned to an ItemType, or if it´s possible to just show it in one specific relationship. And how can be pass the relationship item, related item or even parent item from a CUI button? So far I still use regular Actions for this task. I assume this topics get more relevant in the future.
    But if anyone knows a sample for this specific situations, I would be happy to know!

    I didn´t had the possibly to submit this one as community project yet. I somehow still wait that Aras one day will apologize for a few silly bugs in the past. Definitely had a couple of strange encounters when people with no technical background knowledge suddenly think they can improve Innovator by searching a scapegoat. Instead of searching they should better have joined some of the forum discussion or comm-projects, they definitely bring much more benefit .

    But I am also not sure if the potential scope of this idea still fits to Innovator 12. We probably cannot cover any event context with one Method. But at least provide enough samples to make daily life easier.

  • Hi Angela,

    The scope of this idea definitely still fits in with 12.0. The ability to reuse code is always appreciated.

    To answer your question about CUI in relationship grids, the same concepts for adding global CUI or ItemType-specific CUI still apply. Once you get the general approach for working with CUI, the same steps can be used for basically any section of the UI that you're looking to modify. The biggest thing that's going to change is the Location. If you follow along with the ItemType-specific CUI blog post, you would need to use the ItemView.RelationshipsCommandBar location instead of the ItemView.ItemCommandBar location in order to add your menu options to the relationships grid.

    In this case, we can look at Part BOM as an example.

    1. Login as admin
    2. Navigate to TOC > Administration > ItemTypes
    3. Search for and open the Part BOM ItemType
    4. Follow the same steps as this blog by adding your configuration under the Client Style tab
      1. The biggest thing to change is using the correct ItemView.RelationshipsCommandBar location

    Chris