Skip to main content
May 25, 2021
Solved

Create Accordion Like UI using Box Layouts

  • May 25, 2021
  • 10 replies
  • 2 views

Hi

I have created an interface where input fields are displayed in multiple stacked box layouts. 

the customer wants that all the other box layouts should be collapsed if another one is click opened. behaving like a web accordion.

Is there any way to do it??

Best answer by csteward

A-ha!  Yes that was my initial intent with save!value from the otherwise useless line 46 :).  Also do like the updatedictionary() theory for specific value updates vs rebuilding the entire local!boxes map on each click, albeit a plugin usage.  Which probably 99% of customers do have installed.

I did note in the 21.2 webinar today that we are getting an OOTB a!update() function to handle these CDT updates at specific indexes soon, about time!

a!localVariables(
  local!boxes: a!forEach(
    items: enumerate(5),
    expression: a!map(
      label: concat("Box ",fv!index),
      visible: fv!isFirst
    )
  ),
  a!forEach(
    items: local!boxes,
    expression: {
      a!cardLayout(
        style: "ACCENT",
        marginBelow: if(fv!item.visible,"NONE","STANDARD"),
        showBorder: false,
        contents: {
          a!columnsLayout(
            columns: {
              a!columnLayout(
                contents: {
                  a!richTextDisplayField(
                    labelPosition: "COLLAPSED",
                    value: a!richTextItem(
                      text: fv!item.label,
                      style: "STRONG"
                    )
                  )
                }
              ),
              a!columnLayout(
                contents: {
                  a!richTextDisplayField(
                    align: "RIGHT",
                    labelPosition: "COLLAPSED",
                    value: a!richTextIcon(
                      icon: if(fv!item.visible,"angle-down","angle-right"),
                      size: "MEDIUM"
                    )
                  )
                }
              )
            }
          )
        },
        link: a!dynamicLink(
          value: not(fv!item.visible),
          saveInto: {
            a!localVariables(
              local!clickIndex: fv!index,
              a!save(
                local!boxes,
                a!forEach(
                  items: local!boxes,
                  expression: a!map(
                    label: fv!item.label,
                    visible: if(
                      fv!index=local!clickIndex,
                      save!value,
                      false
                    )
                  )
                )
              )
            )
          }
        )
      ),
      a!cardLayout(
        showWhen: fv!item.visible,
        marginBelow: "STANDARD",
        contents: {
          a!textField(label: concat("Data ",fv!index))
        }
      )
    }
  )
)

10 replies

vamsik0002
May 25, 2021

In App market, there is an application called US web design.

It has that Accordion functionality example.

You can try to recreate it.

mikes0011
Brainy
May 25, 2021

Unfortunately the Box Layout component doesn't have any external way of controlling its "collapsed state" (like setting the value of a parameter or variable to something).  However I think if you feel like doing a little tinkering, you could develop a similar-looking layout that's actually a stack of two cards, where the bottom card "collapses" via just being not shown under certain conditions, which you could set to observe the state of an external variable.  You would put the code for this special component all in its own interface, then call it several times from your parent form, which would also contain the logic surrounding collapsing other boxes when you expand a box.

The Expression Guru
csteward
May 25, 2021

Yea, I've been hoping we see a way to force boxes/sections collapsing for a while now, such as an isCollapsed parameter which overrides user control when <> null.  Fingers crossed..

In the interim, you can do this manually as Mike mentions with a!cardLayout().  Sample interface:

a!localVariables(
  local!boxes: a!forEach(
    items: enumerate(5),
    expression: a!map(
      label: concat("Box ",fv!index),
      visible: fv!isFirst
    )
  ),
  a!forEach(
    items: local!boxes,
    expression: {
      a!cardLayout(
        style: "ACCENT",
        marginBelow: if(fv!item.visible,"NONE","STANDARD"),
        showBorder: false,
        contents: {
          a!columnsLayout(
            columns: {
              a!columnLayout(
                contents: {
                  a!richTextDisplayField(
                    labelPosition: "COLLAPSED",
                    value: a!richTextItem(
                      text: fv!item.label,
                      style: "STRONG"
                    )
                  )
                }
              ),
              a!columnLayout(
                contents: {
                  a!richTextDisplayField(
                    align: "RIGHT",
                    labelPosition: "COLLAPSED",
                    value: a!richTextIcon(
                      icon: if(fv!item.visible,"angle-down","angle-right"),
                      size: "MEDIUM"
                    )
                  )
                }
              )
            }
          )
        },
        link: a!dynamicLink(
          value: not(fv!item.visible),
          saveInto: {
            a!localVariables(
              local!clickIndex: fv!index,
              a!save(
                local!boxes,
                a!forEach(
                  items: local!boxes,
                  expression: a!map(
                    label: fv!item.label,
                    visible: fv!index=local!clickIndex
                  )
                )
              )
            )
          }
        )
      ),
      a!cardLayout(
        showWhen: fv!item.visible,
        marginBelow: "STANDARD",
        contents: {
          a!textField(label: concat("Data ",fv!index))
        }
      )
    }
  )
)

mikes0011
Brainy
May 25, 2021
such as an isCollapsed parameter which overrides user control when <> null

this has been on my "backlog of things to file a feature request whenever i get a slow day" for a while now, but alas.  If they haven't taken care of actual critical issues yet like "allow us to use a base excel template in the Export DSE to Excel node", i'm not sure when they'd get around to little things like this.

The Expression Guru