Editable grid

Hi All, 

I m a beginner in appian. As part of my request, I need to build a editable grid with record data rule input. I have 5 fields totally and I need to display them. Can someone help me how to configure edit button and add button and what actions I need to perform to save or update the values to the rule input. And i should add only one row at a time and all the fields in grid are mandatory. Can someone help me with the code. 

  Discussion posts and replies are publicly visible

Parents
  • 0
    Certified Lead Developer

    There are various recipes in the official documentation: https://docs.appian.com/suite/help/25.1/Editable_Grid_Component.html#record-type-example

    Have you tried anything already and/or having any particular trouble?

  •   I have tried this. I m able to get the data populated in the grid. But I m stuck at how to configure the add , edit and save buttons

  • Everytime when i edit add new row gets added into database. The above receipe i m not able to find configuring edit

  • 0
    Certified Lead Developer
    in reply to reenab0003

    Ensure that when you are editing, the primary key id column value is not overwritten. If originally id was 2 then after edit operation and submits also the id for that row still be 2. If it goes null somewhere then you will find a new row in database instead of the original row being updated. So look out for the 'id' column value in your interface and process. 

  • 0
    Certified Lead Developer
    in reply to reenab0003
    Everytime when i edit add new row gets added into database

    Without seeing the code you're attempting to use, it's hard to guess at a fix, fwiw.

  • a!localVariables(
      local!sectionValue: index(
        ri!sectionDetails,
        'recordType!{9d43eebd-bb55-4fcd-ac73-cce13c477378}TTPK_r_pstConfiguration.fields.{4699341c-986d-4876-808e-d8db1ab0484d}sectionValue',
        null()
      ),
      local!originalParseJson: if(
        a!isNullOrEmpty(local!sectionValue),
        null(),
        a!forEach(
          items: local!sectionValue,
          expression: a!fromJson(fv!item)
        )
      ),
      local!editingRowIndex,
      local!parseJson: local!originalParseJson,
      local!dataToWrite: a!forEach(
        items: ri!sectionDetails,
        expression: cast(
          'recordType!{9d43eebd-bb55-4fcd-ac73-cce13c477378}TTPK_r_pstConfiguration',
          fv!item
        )
      ),
      local!extractKey: a!keys(index(local!parseJson, 1, null())),
      local!headers: a!forEach(
        local!extractKey,
        displayvalue(
          fv!item,
          cons!TTPK_TXT_JSON_PARAMETERS,
          cons!TTPK_TXT_COLUMN_LABELS,
          null()
        )
      ),
      local!isLogisticsLevelCollapse: false(),
      local!isEditable: false,
      local!isNewRow: false,
      local!disableCancel: true,
      local!disableSave: true,
      {
        a!sideBySideLayout(
          items: {
            a!sideBySideItem(
              item: a!richTextDisplayField(
                labelPosition: "COLLAPSED",
                value: {
                  a!richTextItem(
                    text: {
                      'translation!{4813a583-da1f-481b-adb1-124a9b27e0a6}TTPK Translations.{2fab036a-523a-424c-96a0-2e73bb424007}Logistics Impact Levels'
                    },
                    size: "STANDARD",
                    style: "STRONG"
                  )
                },
                marginAbove: "STANDARD"
              )
            ),
            a!sideBySideItem(
              item: a!richTextDisplayField(
                value: a!richTextIcon(
                  icon: if(
                    local!isLogisticsLevelCollapse,
                    "caret-down",
                    "caret-up"
                  ),
                  link: a!dynamicLink(
                    saveInto: {
                      a!save(
                        local!isLogisticsLevelCollapse,
                        not(local!isLogisticsLevelCollapse)
                      )
                    }
                  ),
                  linkStyle: "STANDALONE",
                  color: "#008294",
                  size: "MEDIUM"
                ),
                align: "RIGHT"
              )
            )
          }
        ),
        a!horizontalLine(marginAbove: "NONE", marginBelow: "LESS"),
        a!cardLayout(
          contents: {
            a!gridLayout(
              label: "",
              labelPosition: "ABOVE",
              headerCells: {
                a!gridLayoutHeaderCell(
                  label: 'translation!{4813a583-da1f-481b-adb1-124a9b27e0a6}TTPK Translations.{04c61647-fadb-43ec-876c-119024f26a05}Logistics Impact'
                ),
                a!gridLayoutHeaderCell(
                  label: 'translation!{4813a583-da1f-481b-adb1-124a9b27e0a6}TTPK Translations.{82d09d08-4553-49ea-82ee-85ea089c9298}Operator'
                ),
                a!gridLayoutHeaderCell(
                  label: 'translation!{4813a583-da1f-481b-adb1-124a9b27e0a6}TTPK Translations.{a3643f4a-801c-4e26-b824-e347f80959dd}Previous From'
                ),
                a!gridLayoutHeaderCell(
                  label: 'translation!{4813a583-da1f-481b-adb1-124a9b27e0a6}TTPK Translations.{9978e4b7-d23e-4d2d-b460-6ce00b7332f9}Previous To'
                ),
                a!gridLayoutHeaderCell(
                  label: 'translation!{4813a583-da1f-481b-adb1-124a9b27e0a6}TTPK Translations.{abbf3ef4-fa23-4e52-9e95-ee0708a58a68}From'
                ),
                a!gridLayoutHeaderCell(
                  label: 'translation!{4813a583-da1f-481b-adb1-124a9b27e0a6}TTPK Translations.{d932cdec-954d-4707-8950-9bda619fcc4c}To'
                ),
                a!gridLayoutHeaderCell(label: ""),
                
              },
              columnConfigs: {},
              rows: {
                a!forEach(
                  items: local!parseJson,
                  expression: a!localVariables(
                    a!gridRowLayout(
                      id: fv!index,
                      contents: {
                        a!textField(
                          label: "logisticImpact" & fv!index,
                          value: fv!item.logisticImpact,
                          saveInto: fv!item.logisticImpact,
                          readOnly: true()
                        ),
                        a!textField(
                          /* Labels are not visible in grid cells but are necessary to meet accessibility requirements */
                          label: "operator" & fv!index,
                          value: fv!item.operator,
                          saveInto: fv!item.operator,
                          readOnly: true()
                        ),
                        /* For the Title Column*/
                        a!textField(
                          label: "fromPreviousValue" & fv!index,
                          value: fv!item.fromPreviousValue,
                          saveInto: fv!item.fromPreviousValue,
                          readOnly: true()
                        ),
                        /* For the Phone Number Column*/
                        a!textField(
                          label: "toPreviousValue" & fv!index,
                          value: fv!item.toPreviousValue,
                          saveInto: fv!item.toPreviousValue,
                          readOnly: true()
                        ),
                        a!textField(
                          label: "from" & fv!index,
                          value: fv!item.from,
                          saveInto: fv!item.from,
                          readOnly: if(
                            a!isNullOrEmpty(local!editingRowIndex),
                            true,
                            if(
                              local!editingRowIndex = fv!index,
                              false,
                              true
                            )
                          )
                        ),
                        a!textField(
                          label: "to" & fv!index,
                          value: fv!item.to,
                          saveInto: fv!item.to,
                          disabled: not(
                            if(
                              fv!item.logisticImpact = "High",
                              true,
                              false
                            )
                          ),
                          readOnly: if(
                            a!isNullOrEmpty(local!editingRowIndex),
                            true,
                            if(
                              local!editingRowIndex = fv!index,
                              false,
                              true
                            )
                          )
                        ),
                        a!richTextDisplayField(
                          value: a!richTextIcon(
                            icon: "pencil",
                            linkStyle: "STANDALONE",
                            caption: "Click here to edit",
                            link: a!dynamicLink(
                              saveInto: {
                                a!save(local!editingRowIndex, fv!index),
                                a!save(local!disableCancel, false),
                                a!save(local!disableSave, false)
                              }
                            )
                          )
                        )
                      }
                    )
                  )
                )
              },
              selectionSaveInto: {},
              validations: {},
              shadeAlternateRows: true
            ),
            a!columnsLayout(
              columns: {
                a!columnLayout(
                  contents: {
                    a!buttonArrayLayout(
                      buttons: {
                        a!buttonWidget(
                          label: 'translation!{4813a583-da1f-481b-adb1-124a9b27e0a6}TTPK Translations.{015775ca-76af-416a-9011-4c84f861f9b6}Cancel',
                          style: "LINK",
                          color: "#008294",
                          saveInto: a!save(
                            local!parseJson,
                            local!originalParseJson
                          )
                        ),
                        a!buttonWidget(
                          label: 'translation!{4813a583-da1f-481b-adb1-124a9b27e0a6}TTPK Translations.{1dcf6341-4906-4546-a0f1-074350544f5f}Save',
                          icon: "floppy-o",
                          style: "OUTLINE",
                          color: "#008294",
                          saveInto: {
                            a!save(
                              ri!sectionDetails,
                              a!forEach(
                                items: local!parseJson,
                                expression: a!map(
                                  sectionName: "Logistics Impact Levels",
                                  sectionValue: a!toJson(fv!item),
                                  createdBy: loggedInUser(),
                                  createdOn: now(),
                                  modifiedBy: loggedInUser(),
                                  modifiedOn: now(),
                                  isActive: true()
                                )
                              )
                            ),
                            a!writeRecords(
                              records: local!dataToWrite,
                              onSuccess: a!save(local!isNewRow, true),
                              onError: a!save(local!isNewRow, fv!error)
                            )
                          }
                        ),
                        
                      },
                      align: "END",
                      marginBelow: "NONE"
                    )
                  }
                )
              }
            )
          },
          showWhen: if(
            local!isLogisticsLevelCollapse,
            false,
            true
          ),
          showBorder: false()
        )
      }

Reply
  • a!localVariables(
      local!sectionValue: index(
        ri!sectionDetails,
        'recordType!{9d43eebd-bb55-4fcd-ac73-cce13c477378}TTPK_r_pstConfiguration.fields.{4699341c-986d-4876-808e-d8db1ab0484d}sectionValue',
        null()
      ),
      local!originalParseJson: if(
        a!isNullOrEmpty(local!sectionValue),
        null(),
        a!forEach(
          items: local!sectionValue,
          expression: a!fromJson(fv!item)
        )
      ),
      local!editingRowIndex,
      local!parseJson: local!originalParseJson,
      local!dataToWrite: a!forEach(
        items: ri!sectionDetails,
        expression: cast(
          'recordType!{9d43eebd-bb55-4fcd-ac73-cce13c477378}TTPK_r_pstConfiguration',
          fv!item
        )
      ),
      local!extractKey: a!keys(index(local!parseJson, 1, null())),
      local!headers: a!forEach(
        local!extractKey,
        displayvalue(
          fv!item,
          cons!TTPK_TXT_JSON_PARAMETERS,
          cons!TTPK_TXT_COLUMN_LABELS,
          null()
        )
      ),
      local!isLogisticsLevelCollapse: false(),
      local!isEditable: false,
      local!isNewRow: false,
      local!disableCancel: true,
      local!disableSave: true,
      {
        a!sideBySideLayout(
          items: {
            a!sideBySideItem(
              item: a!richTextDisplayField(
                labelPosition: "COLLAPSED",
                value: {
                  a!richTextItem(
                    text: {
                      'translation!{4813a583-da1f-481b-adb1-124a9b27e0a6}TTPK Translations.{2fab036a-523a-424c-96a0-2e73bb424007}Logistics Impact Levels'
                    },
                    size: "STANDARD",
                    style: "STRONG"
                  )
                },
                marginAbove: "STANDARD"
              )
            ),
            a!sideBySideItem(
              item: a!richTextDisplayField(
                value: a!richTextIcon(
                  icon: if(
                    local!isLogisticsLevelCollapse,
                    "caret-down",
                    "caret-up"
                  ),
                  link: a!dynamicLink(
                    saveInto: {
                      a!save(
                        local!isLogisticsLevelCollapse,
                        not(local!isLogisticsLevelCollapse)
                      )
                    }
                  ),
                  linkStyle: "STANDALONE",
                  color: "#008294",
                  size: "MEDIUM"
                ),
                align: "RIGHT"
              )
            )
          }
        ),
        a!horizontalLine(marginAbove: "NONE", marginBelow: "LESS"),
        a!cardLayout(
          contents: {
            a!gridLayout(
              label: "",
              labelPosition: "ABOVE",
              headerCells: {
                a!gridLayoutHeaderCell(
                  label: 'translation!{4813a583-da1f-481b-adb1-124a9b27e0a6}TTPK Translations.{04c61647-fadb-43ec-876c-119024f26a05}Logistics Impact'
                ),
                a!gridLayoutHeaderCell(
                  label: 'translation!{4813a583-da1f-481b-adb1-124a9b27e0a6}TTPK Translations.{82d09d08-4553-49ea-82ee-85ea089c9298}Operator'
                ),
                a!gridLayoutHeaderCell(
                  label: 'translation!{4813a583-da1f-481b-adb1-124a9b27e0a6}TTPK Translations.{a3643f4a-801c-4e26-b824-e347f80959dd}Previous From'
                ),
                a!gridLayoutHeaderCell(
                  label: 'translation!{4813a583-da1f-481b-adb1-124a9b27e0a6}TTPK Translations.{9978e4b7-d23e-4d2d-b460-6ce00b7332f9}Previous To'
                ),
                a!gridLayoutHeaderCell(
                  label: 'translation!{4813a583-da1f-481b-adb1-124a9b27e0a6}TTPK Translations.{abbf3ef4-fa23-4e52-9e95-ee0708a58a68}From'
                ),
                a!gridLayoutHeaderCell(
                  label: 'translation!{4813a583-da1f-481b-adb1-124a9b27e0a6}TTPK Translations.{d932cdec-954d-4707-8950-9bda619fcc4c}To'
                ),
                a!gridLayoutHeaderCell(label: ""),
                
              },
              columnConfigs: {},
              rows: {
                a!forEach(
                  items: local!parseJson,
                  expression: a!localVariables(
                    a!gridRowLayout(
                      id: fv!index,
                      contents: {
                        a!textField(
                          label: "logisticImpact" & fv!index,
                          value: fv!item.logisticImpact,
                          saveInto: fv!item.logisticImpact,
                          readOnly: true()
                        ),
                        a!textField(
                          /* Labels are not visible in grid cells but are necessary to meet accessibility requirements */
                          label: "operator" & fv!index,
                          value: fv!item.operator,
                          saveInto: fv!item.operator,
                          readOnly: true()
                        ),
                        /* For the Title Column*/
                        a!textField(
                          label: "fromPreviousValue" & fv!index,
                          value: fv!item.fromPreviousValue,
                          saveInto: fv!item.fromPreviousValue,
                          readOnly: true()
                        ),
                        /* For the Phone Number Column*/
                        a!textField(
                          label: "toPreviousValue" & fv!index,
                          value: fv!item.toPreviousValue,
                          saveInto: fv!item.toPreviousValue,
                          readOnly: true()
                        ),
                        a!textField(
                          label: "from" & fv!index,
                          value: fv!item.from,
                          saveInto: fv!item.from,
                          readOnly: if(
                            a!isNullOrEmpty(local!editingRowIndex),
                            true,
                            if(
                              local!editingRowIndex = fv!index,
                              false,
                              true
                            )
                          )
                        ),
                        a!textField(
                          label: "to" & fv!index,
                          value: fv!item.to,
                          saveInto: fv!item.to,
                          disabled: not(
                            if(
                              fv!item.logisticImpact = "High",
                              true,
                              false
                            )
                          ),
                          readOnly: if(
                            a!isNullOrEmpty(local!editingRowIndex),
                            true,
                            if(
                              local!editingRowIndex = fv!index,
                              false,
                              true
                            )
                          )
                        ),
                        a!richTextDisplayField(
                          value: a!richTextIcon(
                            icon: "pencil",
                            linkStyle: "STANDALONE",
                            caption: "Click here to edit",
                            link: a!dynamicLink(
                              saveInto: {
                                a!save(local!editingRowIndex, fv!index),
                                a!save(local!disableCancel, false),
                                a!save(local!disableSave, false)
                              }
                            )
                          )
                        )
                      }
                    )
                  )
                )
              },
              selectionSaveInto: {},
              validations: {},
              shadeAlternateRows: true
            ),
            a!columnsLayout(
              columns: {
                a!columnLayout(
                  contents: {
                    a!buttonArrayLayout(
                      buttons: {
                        a!buttonWidget(
                          label: 'translation!{4813a583-da1f-481b-adb1-124a9b27e0a6}TTPK Translations.{015775ca-76af-416a-9011-4c84f861f9b6}Cancel',
                          style: "LINK",
                          color: "#008294",
                          saveInto: a!save(
                            local!parseJson,
                            local!originalParseJson
                          )
                        ),
                        a!buttonWidget(
                          label: 'translation!{4813a583-da1f-481b-adb1-124a9b27e0a6}TTPK Translations.{1dcf6341-4906-4546-a0f1-074350544f5f}Save',
                          icon: "floppy-o",
                          style: "OUTLINE",
                          color: "#008294",
                          saveInto: {
                            a!save(
                              ri!sectionDetails,
                              a!forEach(
                                items: local!parseJson,
                                expression: a!map(
                                  sectionName: "Logistics Impact Levels",
                                  sectionValue: a!toJson(fv!item),
                                  createdBy: loggedInUser(),
                                  createdOn: now(),
                                  modifiedBy: loggedInUser(),
                                  modifiedOn: now(),
                                  isActive: true()
                                )
                              )
                            ),
                            a!writeRecords(
                              records: local!dataToWrite,
                              onSuccess: a!save(local!isNewRow, true),
                              onError: a!save(local!isNewRow, fv!error)
                            )
                          }
                        ),
                        
                      },
                      align: "END",
                      marginBelow: "NONE"
                    )
                  }
                )
              }
            )
          },
          showWhen: if(
            local!isLogisticsLevelCollapse,
            false,
            true
          ),
          showBorder: false()
        )
      }

Children
  • This is the code i m using, i want to use write records functions to write into the database. i have 3 rows of data stored in db and the only thing i can modify is section value column which is stored in json type. I m not able to write into db. ,   can someone please help

  • 0
    Certified Lead Developer
    in reply to reenab0003

    This is an interesting intellectual challenge ...

    Feels like a situation I have been in many times where increasing complexity grew over my head, and I just did not understand anymore what is going on. And it is extremely challenging for us to try to understand what is going on.

    The solution: Take the things you learned on the way, and restart. Use the recipes posted above. Create some separate simple examples to understand how things work. Once done, you learned a lot, and you will end up having much cleaner code, which you can even maintain in the long term.

  • 0
    Certified Lead Developer
    in reply to reenab0003

    I don't see any "add new row" here - and you said previously that there was an issue with "edit add new row", so can you clarify? And if you're trying to edit existing data, the example here makes it really unclear where that existing data is coming from (how it's being queried, if/how it's being transformed before shown in the grid, etc).

    (Also, I strongly support Stefan's advice - it's almost always best to start with a smaller/simpler working example, and only add new things one-by-one and don't add anything beyond that until you fully understand the last addition and get it 100% working.)