Issue in editable grid bulk selection

Certified Senior Developer

Hi All,

I am having editable grid with selection and implemented pagination also for that grid. For selection given primary key for id in gridRowLayout.

but issue is if I selected all records in first page by click on header level checkbox and and go to next page and select all rows there also in same manner then my first page all selected primary keys is replacing with second page selected primary keys instead of appending all the selected primary key.

Please help in this

  Discussion posts and replies are publicly visible

  • 0
    Certified Lead Developer

    Did you consider to add a separate button to select all items across pages?

  • 0
    Certified Lead Developer

    I would assume you can build some conditionality into your Selection Save Into, in order to check whether the save target already contains some value, and instead of overwriting it, append to it...

  • 0
    Certified Senior Developer
    in reply to Stefan Helzle

    Thanks for the response, Stefan...

    No, I am not using a separate button to select all; I am using the grid selection label level checkbox. Highlighted one

  • 0
    Certified Lead Developer
    in reply to ganeshg0004

    I know that you are not using the built in function. But did you consider to add a separate button?

  • 0
    Certified Senior Developer
    in reply to Stefan Helzle

    No, I did not.

    let me ping code also

    a!localVariables(
    local!items: {
    a!map(id: 1, summary: "Item 1", qty: 1, unitPrice: 10, dept: "Sales", due: today() + 10),
    a!map(id: 2, summary: "Item 2", qty: 2, unitPrice: 20, dept: "Finance", due: today() + 20),
    a!map(id: 3, summary: "Item 3", qty: 3, unitPrice: 30, dept: "Sales", due: today() + 30),
    a!map(id: 4, summary: "Item 4", qty: 1, unitPrice: 10, dept: "Sales", due: today() + 10),
    a!map(id: 5, summary: "Item 5", qty: 2, unitPrice: 20, dept: "Finance", due: today() + 20),
    a!map(id: 6, summary: "Item 6", qty: 3, unitPrice: 30, dept: "Sales", due: today() + 30),
    a!map(id: 7, summary: "Item 7", qty: 1, unitPrice: 10, dept: "Sales", due: today() + 10),
    a!map(id: 8, summary: "Item 8", qty: 2, unitPrice: 20, dept: "Finance", due: today() + 20),
    a!map(id: 9, summary: "Item 9", qty: 3, unitPrice: 30, dept: "Sales", due: today() + 30),
    a!map(id: 10, summary: "Item 10", qty: 1, unitPrice: 10, dept: "Sales", due: today() + 10),
    a!map(id: 11, summary: "Item 11", qty: 2, unitPrice: 20, dept: "Finance", due: today() + 20),
    a!map(id: 12, summary: "Item 13", qty: 3, unitPrice: 30, dept: "Sales", due: today() + 30)

    },
    local!selectedIndices: tointeger({}),
    local!pagingInfo:a!pagingInfo(startIndex: 1,batchSize: 5),
    a!formLayout(
    label: "",
    contents: {
    a!gridLayout(
    headerCells: {
    a!gridLayoutHeaderCell(label: "Summary"),
    a!gridLayoutHeaderCell(label: "Qty", align: "RIGHT"),
    a!gridLayoutHeaderCell(label: "U/P", align: "RIGHT"),
    a!gridLayoutHeaderCell(label: "Amount", align: "RIGHT"),
    a!gridLayoutHeaderCell(label: "Department"),
    a!gridLayoutHeaderCell(label: "Due", align: "RIGHT"),
    a!gridLayoutHeaderCell(label: "Decision"),
    a!gridLayoutHeaderCell(label: "Reason")
    },
    columnConfigs: {
    a!gridLayoutColumnConfig(width: "DISTRIBUTE", weight: 5),
    a!gridLayoutColumnConfig(width: "DISTRIBUTE"),
    a!gridLayoutColumnConfig(width: "DISTRIBUTE"),
    a!gridLayoutColumnConfig(width: "DISTRIBUTE", weight: 2),
    a!gridLayoutColumnConfig(width: "DISTRIBUTE", weight: 3),
    a!gridLayoutColumnConfig(width: "DISTRIBUTE", weight: 3),
    a!gridLayoutColumnConfig(width: "DISTRIBUTE", weight: 3),
    a!gridLayoutColumnConfig(width: "DISTRIBUTE", weight: 3)
    },
    rows: a!forEach(
    items:todatasubset(arrayToPage: local!items,pagingConfiguration: local!pagingInfo),
    expression:{
    a!gridRowLayout(
    id: fv!item.id,
    contents: {
    a!textField(
    /* Labels are not visible in grid cells but are necessary to meet accessibility requirements */
    label: "summary " & fv!index,
    value: fv!item.summary,
    readOnly: true
    ),
    a!integerField(
    label: "qty " & fv!index,
    value: fv!item.qty,
    readOnly: true,
    align: "RIGHT"
    ),
    a!floatingPointField(
    label: "unitPrice " & fv!index,
    value: fv!item.unitPrice,
    readOnly: true,
    align: "RIGHT"
    ),
    a!textField(
    label: "amount " & fv!index,
    value: if(
    or(isnull(fv!item.qty), isnull(fv!item.unitPrice)),
    null,
    a!currency(
    isoCode: "USD",
    value: fv!item.qty * fv!item.unitPrice
    )
    ),
    readOnly: true,
    align: "RIGHT"
    ),
    a!dropdownField(
    choiceLabels: {"Finance", "Sales"},
    choiceValues: {"Finance", "Sales"},
    label: "dept " & fv!index,
    placeholder: "--Select-- ",
    value: fv!item.dept,
    disabled: true
    ),
    a!dateField(
    label: "due " & fv!index,
    value: fv!item.due,
    readOnly: true,
    align: "RIGHT"
    ),
    a!dropdownField(
    choiceLabels: {"Approve", "Reject", "Need More Info"},
    choiceValues: {"Approve", "Reject", "Need More Info"},
    label: "decision " & fv!index,
    placeholder: "--Select-- ",
    value: fv!item.decision,
    saveInto: fv!item.decision,
    required: true
    ),
    a!textField(
    label: "reason" & fv!index,
    value: fv!item.reason,
    saveInto: fv!item.reason,
    required: and(
    not(isnull(fv!item.decision)),
    fv!item.decision <> "Approve"
    ),
    requiredMessage: "A reason is required for items that are not approved"
    )
    }
    )
    }
    ),
    selectionValue: local!selectedIndices,
    selectionSaveInto: a!save(local!selectedIndices, a!flatten(save!value)),
    selectable: true,
    rowHeader: 2
    ),
    a!richTextDisplayField(
    labelPosition: "COLLAPSED",
    value: {
    a!richTextIcon(
    icon: "angle-left-bold",
    link: a!dynamicLink(
    saveInto: a!save(local!pagingInfo.startIndex,local!pagingInfo.startIndex-local!pagingInfo.batchSize)
    )
    ),
    local!pagingInfo.startIndex&" to "&sum(tointeger(local!pagingInfo.startIndex),tointeger(local!pagingInfo.batchSize))-1,
    a!richTextIcon(
    icon: "angle-right-bold",
    link: a!dynamicLink(
    saveInto: a!save(local!pagingInfo.startIndex,tointeger(local!pagingInfo.startIndex)+tointeger(local!pagingInfo.batchSize))
    )
    )
    },
    align: "RIGHT"
    )

    },
    )
    )

  • 0
    Certified Senior Developer
    in reply to Stefan Helzle

    a!localVariables(
      local!items: {
        a!map(id: 1, summary: "Item 1", qty: 1, unitPrice: 10, dept: "Sales",   due: today() + 10),
        a!map(id: 2, summary: "Item 2", qty: 2, unitPrice: 20, dept: "Finance", due: today() + 20),
        a!map(id: 3, summary: "Item 3", qty: 3, unitPrice: 30, dept: "Sales",   due: today() + 30),
        a!map(id: 4, summary: "Item 4", qty: 1, unitPrice: 10, dept: "Sales",   due: today() + 10),
        a!map(id: 5, summary: "Item 5", qty: 2, unitPrice: 20, dept: "Finance", due: today() + 20),
        a!map(id: 6, summary: "Item 6", qty: 3, unitPrice: 30, dept: "Sales",   due: today() + 30),
        a!map(id: 7, summary: "Item 7", qty: 1, unitPrice: 10, dept: "Sales",   due: today() + 10),
        a!map(id: 8, summary: "Item 8", qty: 2, unitPrice: 20, dept: "Finance", due: today() + 20),
        a!map(id: 9, summary: "Item 9", qty: 3, unitPrice: 30, dept: "Sales",   due: today() + 30),
        a!map(id: 10, summary: "Item 10", qty: 1, unitPrice: 10, dept: "Sales",   due: today() + 10),
        a!map(id: 11, summary: "Item 11", qty: 2, unitPrice: 20, dept: "Finance", due: today() + 20),
        a!map(id: 12, summary: "Item 13", qty: 3, unitPrice: 30, dept: "Sales",   due: today() + 30)
        
      },
      local!selectedIndices: tointeger({}),
      local!pagingInfo:a!pagingInfo(startIndex: 1,batchSize: 5),
      a!formLayout(
        label: "",
        contents: {
          a!gridLayout(
            headerCells: {
              a!gridLayoutHeaderCell(label: "Summary"),
              a!gridLayoutHeaderCell(label: "Qty", align: "RIGHT"),
              a!gridLayoutHeaderCell(label: "U/P", align: "RIGHT"),
              a!gridLayoutHeaderCell(label: "Amount", align: "RIGHT"),
              a!gridLayoutHeaderCell(label: "Department"),
              a!gridLayoutHeaderCell(label: "Due", align: "RIGHT"),
              a!gridLayoutHeaderCell(label: "Decision"),
              a!gridLayoutHeaderCell(label: "Reason")
            },
            columnConfigs: {
              a!gridLayoutColumnConfig(width: "DISTRIBUTE", weight: 5),
              a!gridLayoutColumnConfig(width: "DISTRIBUTE"),
              a!gridLayoutColumnConfig(width: "DISTRIBUTE"),
              a!gridLayoutColumnConfig(width: "DISTRIBUTE", weight: 2),
              a!gridLayoutColumnConfig(width: "DISTRIBUTE", weight: 3),
              a!gridLayoutColumnConfig(width: "DISTRIBUTE", weight: 3),
              a!gridLayoutColumnConfig(width: "DISTRIBUTE", weight: 3),
              a!gridLayoutColumnConfig(width: "DISTRIBUTE", weight: 3)
            },
            rows: a!forEach(
              items:todatasubset(arrayToPage: local!items,pagingConfiguration: local!pagingInfo),
              expression:{
                a!gridRowLayout(
                  id: fv!item.id,
                  contents: {
                    a!textField(
                      /* Labels are not visible in grid cells but are necessary to meet accessibility requirements */
                      label: "summary " & fv!index,
                      value: fv!item.summary,
                      readOnly: true
                    ),
                    a!integerField(
                      label: "qty " & fv!index,
                      value: fv!item.qty,
                      readOnly: true,
                      align: "RIGHT"
                    ),
                    a!floatingPointField(
                      label: "unitPrice " & fv!index,
                      value: fv!item.unitPrice,
                      readOnly: true,
                      align: "RIGHT"
                    ),
                    a!textField(
                      label: "amount " & fv!index,
                      value: if(
                        or(isnull(fv!item.qty), isnull(fv!item.unitPrice)),
                        null,
                        a!currency(
                          isoCode: "USD",
                          value: fv!item.qty * fv!item.unitPrice
                        )
                      ),
                      readOnly: true,
                      align: "RIGHT"
                    ),
                    a!dropdownField(
                      choiceLabels: {"Finance", "Sales"},
                      choiceValues: {"Finance", "Sales"},
                      label: "dept " & fv!index,
                      placeholder: "--Select-- ",
                      value: fv!item.dept,
                      disabled: true
                    ),
                    a!dateField(
                      label: "due " & fv!index,
                      value: fv!item.due,
                      readOnly: true,
                      align: "RIGHT"
                    ),
                    a!dropdownField(
                      choiceLabels: {"Approve", "Reject", "Need More Info"},
                      choiceValues: {"Approve", "Reject", "Need More Info"},
                      label: "decision " & fv!index,
                      placeholder: "--Select-- ",
                      value: fv!item.decision,
                      saveInto: fv!item.decision,
                      required: true
                    ),
                    a!textField(
                      label: "reason" & fv!index,
                      value: fv!item.reason,
                      saveInto: fv!item.reason,
                      required: and(
                        not(isnull(fv!item.decision)),
                        fv!item.decision <> "Approve"
                      ),
                      requiredMessage: "A reason is required for items that are not approved"
                    )
                  }
                )
              }
            ),
            selectionValue: local!selectedIndices,
            selectionSaveInto: a!save(local!selectedIndices, a!flatten(save!value)),
            selectable: true,
            rowHeader: 2
          ),
          a!richTextDisplayField(
            labelPosition: "COLLAPSED",
            value: {
              a!richTextIcon(
                icon: "angle-left-bold",
                link: a!dynamicLink(
                  saveInto: a!save(local!pagingInfo.startIndex,local!pagingInfo.startIndex-local!pagingInfo.batchSize)
                )
              ),
              local!pagingInfo.startIndex&" to "&sum(tointeger(local!pagingInfo.startIndex),tointeger(local!pagingInfo.batchSize))-1,
              a!richTextIcon(
                icon: "angle-right-bold",
                link: a!dynamicLink(
                  saveInto: a!save(local!pagingInfo.startIndex,tointeger(local!pagingInfo.startIndex)+tointeger(local!pagingInfo.batchSize))
                )
              )
            },
            align: "RIGHT"
          )
        
        },
      )
    )

  • 0
    Certified Senior Developer
    in reply to Mike Schmitt

    Thanks for the response, Mike...

    I have tried to append instead of override. It is appending the next page selected all IDs, but when I try to deselect any row, that is not happening. It is always being selected. 

    I tried like this.

    selectionValue: local!selectedIndices,
            selectionSaveInto: if(
              a!isNullOrEmpty(local!selectedIndices),
              a!save(
                local!selectedIndices,
                a!flatten(save!value)
              ),
              a!save(
                local!selectedIndices,
                append(
                  local!selectedIndices,
                  a!flatten(save!value)
                )
              )
            )

  • 0
    Certified Senior Developer
    in reply to ganeshg0004

    Hi  

    The issue is with the "Select All" functionality. When you select all values using it and then navigate to the next page and select all again, it overrides the previously selected values. However, this issue does not occur if you manually select each value one by one, move to the next page, and continue the same process — in that case, the select and deselect functionality works as expected.

    I would suggest the following options to resolve this:

    1. Build a custom "Select All" functionality.

    2. Alternatively, change the selection style to ROW_HIGHLIGHT.

    selectionValue: local!selectedIndices,
    selectionSaveInto: a!save(
              local!selectedIndices,
              a!flatten(save!value)
            ),
    selectionStyle: "ROW_HIGHLIGHT"

  • 0
    Certified Senior Developer
    in reply to Vyshnavi Naripeddi

    Thanks Vyshnavi, for the suggestion...

    I have fixed this issue by applying a condition for "select all" and "deselect all" in the selection save into as per below

     selectionValue: local!selectedIndices,
            selectionSaveInto: a!save(
              local!selectedIndices,
              if(
                a!isNullOrEmpty(index(save!value,1,null)),
                difference(local!selectedIndices,local!gridData.data.id),
                if(
                  length(wherecontains(local!gridData.data.id,tointeger(save!value)))=length(local!gridData.data),
                  union(append(local!selectedIndices,a!flatten(save!value)),append(local!selectedIndices,a!flatten(save!value)))
                  a!flatten(save!value)
                )
              )
            ),