Pagination in Editable Grid

Hi,

1)I want to Implement pagination in Editable Grid please guide me.

2)Add sorting arrows in Editable Grid header columns for sorting purpose.

Appreciate your help!!

Regards

Nishtha Bhatnagar

  Discussion posts and replies are publicly visible

Parents
  • On top of what Danny proposed as a solution, you can create the pagination functionality itself as a common component for use also in other Grids. 

    You only have to create a generic interface with only 3 rule inputs:

    startIndex (int):  pass the pagingInfo.startIndex,

    batchSize (int): pass the pagingInfo.batshSize,

    totalCount (int): pass the local!datasubset.data

    and make a call of this common interface after your grid and you will be fine. 

    a!localVariables(
      a!sideBySideLayout(
        items: {
          a!sideBySideItem(
            item: a!richTextDisplayField(
              align: "RIGHT",
              value: {
                /* Left Angle */
                a!richTextIcon(
                  icon: "angle-double-left",
                  link: a!dynamicLink(
                    saveInto: {
                      a!save(ri!startIndex, 1),                  
                    },
                    showWhen: ri!startIndex <> 1
                  ),
                  linkStyle: "STANDALONE",
                  color: if(
                    ri!startIndex <> 1,
                    "STANDARD",
                    "SECONDARY"
                  )
                ),
                a!richTextIcon(
                  icon: "angle-left",
                  link: a!dynamicLink(
                    showWhen: ri!startIndex <> 1,
                    saveInto: a!save(
                      ri!startIndex,
                      ri!startIndex - ri!batchSize
                    )
                  ),
                  linkStyle: "STANDALONE",
                  color: if(
                    ri!startIndex <> 1,
                    "STANDARD",
                    "SECONDARY"
                  )
                ),
                /* Start Index */
                a!richTextItem(
                  text: {
                    ri!startIndex, 
                    " - ",
                    if(
                      ri!startIndex + ri!batchSize - 1 > ri!totalCount,
                      ri!totalCount,
                      ri!startIndex + ri!batchSize - 1
                    )
                  },
                  style: "STRONG"
                ),
                /* Total Count */
                a!richTextItem(
                  text: {
                    " of ", 
                    ri!totalCount
                  }
                ),
                /* Right Angle */
                a!richTextIcon(
                  icon: "angle-right",
                  link: a!dynamicLink(
                    showWhen: (ri!startIndex + ri!batchSize - 1) < ri!totalCount,
                    label: "",
                    saveInto: a!save(
                      ri!startIndex,
                      ri!startIndex + ri!batchSize
                    )
                  ),
                  linkStyle: "STANDALONE",
                  color: if(                
                    ri!startIndex + ri!batchSize - 1 < ri!totalCount,                
                    "STANDARD",
                    "SECONDARY"
                  )           
                ),
                a!richTextIcon(
                  icon: "angle-double-right",
                  link: a!dynamicLink(
                    saveInto: {
                      a!save(
                        ri!startIndex, 
                        if(
                          mod(ri!totalCount, ri!batchSize) = 0,
                          ri!totalCount - ri!batchSize + 1,
                          ri!totalCount - mod(ri!totalCount, ri!batchSize) + 1
                        )
                      )
                    },
                    showWhen: ri!startIndex + ri!batchSize - 1 < ri!totalCount
                  ),
                  linkStyle: "STANDALONE",
                  color: if(                
                    ri!startIndex + ri!batchSize - 1 < ri!totalCount,                
                    "STANDARD",
                    "SECONDARY"
                  )
                )
              }
            )
          )
        }
      )
    )

  • Hi ,

    Thanks for reply .Appreciate if you can show how to use this function  . 

    Regards

    Nishtha

  • You have everything you need written above on my previous comment. The code for the pagination functionality and how to setup the rule.. Just copy and paste it. That's all.

  • 0
    Certified Senior Developer
    in reply to jojog0002

    Dimitris explained it pretty well.
    Its one way to solve it, but a pretty valid one.
    -> jojog, what are you missing exactly?

  • 0
    Certified Lead Developer
    in reply to Dimitris Soulovaris

    As I noted in the other thread... as far as I can tell from this code, the row-level user changes are only saved up as far as the dataSubset (and i don't see any code that propagates such changes any further than that), but of course that's all overwritten the second the user changes pages. 

    Some additional SaveInto bending-over-backwards would need to be added to promote any user changes back to the source data, but of course at that point, we're talking about such complicated code that most devs would have saved days of heartache and headache by just implementing a paging grid with a row-level "edit" button.

  • Hi Mike,

    Yes, you are right about everything you mentioned for the non-saved data. In the current implementation, the modified values are not being saved.

    He has to save the data in the source as you said. Therefore, he should do the data saving inside the grid and after editing.

    Here it is what he needs to do exactly: 

    jojog0002

    The pagination functionality remains as is.

  • 0
    Certified Lead Developer
    in reply to Dimitris Soulovaris

    That works on the first page.  But on subsequent pages, the value of fv!index (i.e. for the first row on the new page) will be "1", whereas the index you're actually trying to save into in the source data would be "1" + (page size * (page number - 1)).  In the above code, if you're on page 2 and you update row 1, you'd actually be saving into the field for page 1's row 1.

    This can be fixed with yet more saveInto hijinks - though as you can see the rabbit hole just keeps getting deeper.  I've always found it pretty unmanageable and, frankly, not worth the hassle when compared to a simple and elegant solution like a read-only grid with a row-by-row "edit" button.

  • You right. Didn't test the second page at all..LOL

    It needs the fv!identifier instead of the fv!index.

    But as you said, it's becoming more complex. But that's a good task for the reporter so he can practice more on Appian. 

  • Hii  Dimitris,

    when we go on second page then we can click on add employee then new row appears then we try to delete it then it deleted above row with data and blank row is still there.

    /* For the Removal Column*/
                  a!richTextDisplayField(
                    value: a!richTextIcon(
                      icon: "trash-o",
                      altText: "delete " & fv!index,
                      caption: "Remove " & fv!item.FirstName & " " & fv!item.LastName,
                      link: a!dynamicLink(
                        value: fv!index,
                        saveInto: {
                          if(
                            isnull(fv!item.Id),
                            {},
                            a!save(
                              local!deletedEmployeeIds,
                              append(local!deletedEmployeeIds, fv!item.Id)
                            )
                          ),
                          a!save(ri!Del, true),
                          a!save(ri!Del_Id, local!deletedEmployeeIds),
                          a!save(
                            local!Employeedata,
                            remove(local!Employeedata, save!value)
                          )
                        }
                      ),
                      linkStyle: "STANDALONE",
                      color: "NEGATIVE"
                    )
                  )
                }
              )
            ),

  • 0
    Certified Lead Developer
    in reply to jojog0002
    when we go on second page then we can click on add employee then new row appears then we try to delete it then it deleted above row

    This is because of the issue I mentioned yesterday.  "fv!index" will always be relative to the current page of data, whereas if you're on a subsequent page and you try to edit/remove an entry on that page (anchoring on fv!index), you'll really be editing/removing the indicated entry from the first page.

    The real solution to this, if you insist on continuing down this rabbit hole, is to declare row-specific local variables.  Inside the row's local variable definition, you insert logic to give you the index in the original array of source data corresponding to the current row.  Thus, on page 2 (assuming you have a page size of 10 for example), your rows will have "local!rowIndex" values of 11 - 20, instead of fv!index which would still be 1 - 10.   Then local!rowIndex can be used in place of "fv!index" in most places in the above code.

    rows: a!forEach(
      items: local!datasubset,
      expression: a!localVariables(
      
        local!rowIndex: where(local!originalArray.id = fv!item.id),
        
        a!gridRowLayout(
          contents: { ....

  • Hii mike,

    This above code gives error. please  give me any other solution

Reply Children
  • 0
    Certified Lead Developer
    in reply to jojog0002

    The code I included above is only meant to serve as a template - the logic for getting the by-row RowIndex will need to be tested/refined by anyone attempting to implement it.  But otherwise, this solution should work and will be the most straightforward way of accomplishing this use case.

    That said - I can't help you with just "gives error".  Can you share what the error says / post a screenshot / etc?