Expand/Collapse Rows within an Expanded/Collapse Row

Certified Associate Developer

Has any one done an expanded/collapse row grid within an expanded/collapse row grid.  I am looking at the https://docs.appian.com/suite/help/23.2/recipe-expand-collapse-rows-in-a-tree-grid.html#expression

in the documentation and it look like what I am looking for, I just need a third level.  I am looking at creating a grid that displays primary customers, then expands to show those primary customers ship to's then another expansion to show the ship to's contacts.

  Discussion posts and replies are publicly visible

  • 0
    Certified Lead Developer

    It should be achievable following the same sort of logic as in that recipe - i don't asusme there are any pre-set recipes offering an additional level of expansion, so my best guess is you'll probably need to work out that logic on your own (though if you're lucky, maybe someone here already has and can post some example code - i haven't).

    One suggestion I could offer here is to write a specialized rule / sub-interface specifically to handle each parent-level grid row (where each iteration would return 1 set if it's non-expanded, and additional sets if it has been expanded), as this sort of encapsulation might make it a little easier to work with in the context of your parent interface.  Though I believe it's not a requirement, so you can probably accomplish this using whichever style ends up being easiest for you to work with.

  • 0
    Certified Associate Developer
    in reply to Mike Schmitt

    Thanks Mike, I love the suggestion, I had not thought about doing that.

    I am working on working out the logic of the recipe to add my third layer.

  • 0
    Certified Associate Developer
    in reply to Stefan Helzle

    Thanks Stefan, I have actually been looking at the building-a-collapsible-tree.  By the way, I love your book, thank you for taking the time to write it and help us novice out.

  • 0
    Certified Lead Developer
    in reply to AllenP

    Is there anything in particular you're still having trouble with here, BTW?

  • 0
    Certified Associate Developer
    in reply to Mike Schmitt

    Thanks Mike.  Right now, I keep confusing myself more and more.  I seem to understand how layer 1 and layer 2 works, but seem to loose it when I attempt to add layer 3.

  • +1
    Certified Lead Developer
    in reply to AllenP

    Well for the sake of argument I've whipped you up a quick example using a probably-oversimplified local data structure, but which might at least help you solidify the necessary "skeleton" of the thing you're trying to build...

    a!localVariables(
      
      local!nestedDataSet: {
        a!map(
          name: "Set 1",
          contents: {
            a!map(
              itemName: "item a1",
              features: {
                a!map(featureName: "feature q1", widgetCount: tointeger(rand()*20)),
                a!map(featureName: "feature q2", widgetCount: tointeger(rand()*20)),
                a!map(featureName: "feature q3", widgetCount: tointeger(rand()*20)),
              }
            ),
            a!map(
              itemName: "item a2",
              features: {
                a!map(featureName: "feature w1", widgetCount: tointeger(rand()*20)),
                a!map(featureName: "feature w2", widgetCount: tointeger(rand()*20)),
                a!map(featureName: "feature w3", widgetCount: tointeger(rand()*20)),
              }
            ),
            a!map(
              itemName: "item a3",
              features: {
                a!map(featureName: "feature e1", widgetCount: tointeger(rand()*20)),
                a!map(featureName: "feature e2", widgetCount: tointeger(rand()*20)),
                a!map(featureName: "feature e3", widgetCount: tointeger(rand()*20)),
              }
            )
          }
        ),
        a!map(
          name: "Set 2",
          contents: {
            a!map(
              itemName: "item b1",
              features: {
                a!map(featureName: "feature r1", widgetCount: tointeger(rand()*20)),
                a!map(featureName: "feature r2", widgetCount: tointeger(rand()*20)),
                a!map(featureName: "feature r3", widgetCount: tointeger(rand()*20)),
              }
            ),
            a!map(
              itemName: "item b2",
              features: {
                a!map(featureName: "feature t1", widgetCount: tointeger(rand()*20)),
                a!map(featureName: "feature t2", widgetCount: tointeger(rand()*20)),
                a!map(featureName: "feature t3", widgetCount: tointeger(rand()*20)),
              }
            ),
            a!map(
              itemName: "item b3",
              features: {
                a!map(featureName: "feature y1", widgetCount: tointeger(rand()*20)),
                a!map(featureName: "feature y2", widgetCount: tointeger(rand()*20)),
                a!map(featureName: "feature y3", widgetCount: tointeger(rand()*20)),
              }
            )
          }
        ),
      },
      
      a!sectionLayout(
        
        contents: {
          a!gridLayout(
            headerCells: {
              a!gridLayoutHeaderCell(label: "Name"),
              a!gridLayoutHeaderCell(label: "Quantity")
            },
            
            rows: a!forEach(
              local!nestedDataSet,
              
              a!localVariables(
                local!currentLevel1: fv!item,
                local!isCurrentLevelExpanded: false(),
                
                {
                  a!gridRowLayout(
                    contents: {
                      a!richTextDisplayField(
                        value: a!richTextItem(
                          text: fv!item.name,
                          link: a!dynamicLink(
                            saveInto: a!save(local!isCurrentLevelExpanded, not(local!isCurrentLevelExpanded))
                          ),
                          linkStyle: "STANDALONE"
                        )
                      ),
                      a!richTextDisplayField(value: "Items: " & length(fv!item.contents))
                    }
                  ),
                  
                  if(
                    local!isCurrentLevelExpanded,
                    
                    a!forEach(
                      local!currentLevel1.contents,
                      a!localVariables(
                        local!currentLevel2: fv!item,
                        local!isCurrentChildLevelExpanded: false(),
                        {
                          a!gridRowLayout(
                            contents: {
                              a!richTextDisplayField(
                                value: {
                                  " -  ",
                                  a!richTextItem(
                                    text: fv!item.itemName,
                                    link: a!dynamicLink(
                                      saveInto: a!save(local!isCurrentChildLevelExpanded, not(local!isCurrentChildLevelExpanded))
                                    )
                                  )
                                }
                              ),
                              a!richTextDisplayField(
                                value: a!richTextItem(
                                  text: "  Features: " & length(fv!item.features),
                                  style: "EMPHASIS"
                                )
                              )
                            }
                          ),
                          
                          if(
                            local!isCurrentChildLevelExpanded,
                            a!forEach(
                              local!currentLevel2.features,
                              a!gridRowLayout(
                                contents: {
                                  a!richTextDisplayField(
                                    value: {
                                      " - -  ",
                                      a!richTextItem(
                                        text: fv!item.featureName,
                                        size: "SMALL"
                                      )
                                    }
                                  ),
                                  a!richTextDisplayField(
                                    value: a!richTextItem(
                                      text: "    Widget Count: " & fv!item.widgetCount,
                                      size: "SMALL"
                                    )
                                  )
                                }
                              )
                            ),
                            {}
                          )
                        }
                      )
                    ),
                    {}
                  )
                }
              )
            )
          )
        }
      )
    )

  • 0
    Certified Associate Developer
    in reply to Mike Schmitt

    WOW, Mike, you are AMAZING!!!  Thank you so much.

  • 0
    Certified Lead Developer
    in reply to AllenP

    lol, thanks - well just let me know if you need any clarifications etc.

  • 0
    Certified Associate Developer
    in reply to Mike Schmitt

    That did exactly what I was looking for.  Thanks a bunch Mike