Create Accordion Like UI using Box Layouts

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??

  Discussion posts and replies are publicly visible

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

    It has that Accordion functionality example.

    You can try to recreate it.

  • 0
    Certified Lead Developer

    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.

  • 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))
            }
          )
        }
      )
    )

  • 0
    Certified Lead Developer
    in reply to Chris
    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.

  • +1
    Certified Lead Developer
    in reply to Chris

    FWIW i tweaked your very nice code above to allow clicking on an open Box if you want to collapse it (thus collapsing all), as that's what i intuitively expect the behavior to be:

    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: updatedictionary(
                        fv!item,
                        {
                          visible: if(
                            fv!index=local!clickIndex,
                            if(
                              fv!item.visible,
                              false(),
                              true()
                            ),
                            false()
                          )
                        }
                      )
                    )
                  )
                )
              }
            )
          ),
          a!cardLayout(
            showWhen: fv!item.visible,
            marginBelow: "STANDARD",
            contents: {
              a!textField(label: concat("Data ",fv!index))
            }
          )
        }
      )
    )

  • 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))
            }
          )
        }
      )
    )

  • 0
    Certified Lead Developer
    in reply to Chris

    Definitely glad we can finally say goodbye to this in 21.2 :)  Though in my 21.2 environment for the LBC, the rule helper wasn't altogether clear how you should do multiple properties at once when needed. I kinda had to guess.  And of course the website with official documentation didn't yet exist.

  • allow us to use a base excel template in the Export DSE to Excel node

    If you hear this question in the 21.3 webinar, it probably came from my keyboard ;)

  • 0
    Certified Lead Developer
    in reply to Chris
    If you hear this question in the 21.3 webinar

    trust me, i've tried :o)

  • Thank You all for this amazing work. 

    Worked like a Charm Slight smile