choose function usage with rule inputs as parameters.

Hello, mates!

I would like to create a rule that will provide choices/options through parameters to be used with the choose() function (https://docs.appian.com/suite/help/25.1/fnc_logical_choose.html)

However, the choices will not have a default length. I tried using Appian array, but as expected, it didn't work because choose() expects individual parameters, not an array.

I'm working on creating a tab interface component, where the number of tabs isn't fixed, hence the need for dynamic choices.

Does anyone have any hint on this? Thanks.

  Discussion posts and replies are publicly visible

Parents Reply Children
  • My component should be something like

    {
      /* Example 1 */
      rule!App_TABS(
        tabs: { "TAB 1", "TAB 2", "TAB 3" },
        contents: {
          rule!APP_content_1(),
          rule!APP_content_2(),
          rule!APP_content_3()
        }
      ),
      
      /* Example 2 */
      rule!App_TABS(
        tabs: { "TAB 1", "TAB 2", "TAB 3", "TAB 4", "TAB 5" },
        contents: {
          rule!APP_content_1(),
          rule!APP_content_2(),
          rule!APP_content_3(),
          rule!APP_content_4(),
          rule!APP_content_5(),
    
    
        }
      )
    }

    The reason is that I want it to become an utility rule.

  • +1
    Certified Lead Developer
    in reply to Silas. B. Ferreira

    You need to figure out at most how many tabs can be there when either all conditions are passed or none applied.

    If you can have at most 7 tabs then your match() needs to be configured with all 7 possibilities. Assign one unique index to each tab so that if dynamically only 4 tabs (e.g. Tabs 1,3,4 and 7) are selected, the indexes replicate the same.

    If it easier you can also go with strings to match the selected tab with content instead of index. 

    a!localVariables(
      local!selectedTab: "Tab2",
      a!match(
        value: local!selectedTab,
        equals: "Tab1",
        then: a!stampField(
          labelPosition: "COLLAPSED",
          icon: "angle-down",
          contentColor: "STANDARD"
        ),
        equals: "Tab2",
        then: a!stampField(
          labelPosition: "COLLAPSED",
          icon: "angle-up",
          contentColor: "STANDARD"
        ),
        equals: "Tab3",
        then: a!stampField(
          labelPosition: "COLLAPSED",
          icon: "angle-double-up",
          contentColor: "STANDARD",
          backgroundColor: "NEGATIVE"
        ),
        default: "No Priority"
      )
    )

  • 0
    Certified Lead Developer
    in reply to Silas. B. Ferreira

    Just as you would need to manually create all rules rule!APP_content_X() for X = 1....n, you would need to hardcode them into your calling interface in some way or another.

    a!match() provides far greater flexibility than choose() in that you don't strictly need an array of strictly n parameters passed into it, but can instead handle anything up to and including n.  But it doesn't, per se, buy you the ability to avoid hardcoding interface names that you need to call.

    (But you might want to look at making all or some of these interfaces programmatic, meaning they share the same interface but act differently depending on a parameter you pass in - if possible, which of course I can't say for sure since I don't know how different they all need to be.)

  • The tab layout will remain the same, but the names and the contents will be different. I don't have the differences mapped, I am just just trying to make that possibility come true, so other mates can utilize for different contents and lengths as a component, that is it.

  • +1
    Certified Lead Developer
    in reply to Silas. B. Ferreira

    Either way you'll need to figure out a way to work within the system's constraints - mainly here that there isn't a supported way to call arbitrarily-named sub-interfaces (or other rules etc); whatever you want to use will need to be hardcoded into the parent interface.  You'll have a lot better time if you architect it in such a way that you can use a limited set of sub-interfaces and parameterize the contents using tab-specific data you pass in (as needed).

  • I appreciate that, but it doesn't meet my use case requirements for development utils.

  • I see, thank you and Harsha as well. I guess I will just componentize the tabs, and use a rule input to store the index back to the whichever main interface use the component, that should work like:

    /*ri!tabs: (Array of Text)*/
    /*ri!activeTab: (Integer store the active tab through index)*/
    
    a!localVariables(
      a!cardLayout(
        contents: {
          a!cardLayout(
            contents: {
              a!columnsLayout(
                columns: {
                  a!forEach(
                    ri!tabs,
                    a!columnLayout(
                      contents: {
                        a!cardLayout(
                          contents: {
                            a!richTextDisplayField(
                              labelPosition: "COLLAPSED",
                              value: {
                                char(10),
                                a!richTextItem(
                                  text: ri!tabs[fv!index],
                                  color: if(
                                    fv!index = ri!activeTab,
                                    "STANDARD",
                                    "ACCENT"
                                  ),
                                  size: "STANDARD",
                                  style: if(fv!index = ri!activeTab, "STRONG", "PLAIN")
                                ),
                                "  ",
                                a!richTextIcon(
                                  icon: "exclamation-triangle",
                                  showWhen: false,
                                  color: "NEGATIVE"
                                )
                              },
                              align: "CENTER"
                            ),
                            a!cardLayout(
                              style: if(fv!index = ri!activeTab, "ACCENT", "NONE"),
                              padding: "EVEN_LESS",
                              showBorder: false
                            )
                          },
                          link: a!dynamicLink(value: fv!index, saveInto: ri!activeTab),
                          padding: "NONE",
                          showBorder: false,
                          accessibilityText: if(
                            fv!index = ri!activeTab,
                            "Selected Tab.",
                            "Unselected Tab. Press enter to select tab."
                          )
                        )
                      },
                      width: "NARROW"
                    )
                  )
                },
                marginBelow: "NONE",
                spacing: "NONE"
              ),
              a!cardLayout(padding: "NONE")
            },
            padding: "NONE",
            showBorder: false
          ),
          
        },
        padding: "NONE",
        showBorder: false
      )
    )