Advance Editable Grid Configurations

Hello everyone,

I'm just looking for some advise on advance editable grid configurations.  See the SAIL code and screenshot below.

I am new to SAIL and have just created the structure of my editable data grid (thanks to Appian documentation).

Now, I am looking for guidance on some advance features:

1. I would like to bind the data source of my editable grid to a CDT.

2. Also looking to dynamically store the result of a multiplication of the qty and amount fields into the Total field.

3. Lastly would like to get the sum of all totals across the rows and save in the AmountTotal field (in a floatingPointField outside the grid).

Thanks in advance.

 

SAIL code

------------

=load(
  /* 
  * local!employess is provided in this recipe as a way to start with hard-coded
  * data. However, this data is identical to the data created from the entity-backed
  * tutorial. Replace the hard-coded data with a query to the employee data store
  * entity and all of the employee records from the tutorial will appear.
  *
  * To replace this data with your own, replace (ctrl+H or cmd+H) all references to
  * local!invoice with your data source, either via rule input or local variable.
  */
  local!invoice: {
      { id: 1, cashAdvnaceId: 1, itemName: "Logitec Mouse" , amount: 74.99 , qty: 3, total: 0.0 },
      { id: 2, cashAdvnaceId: 1, itemName: "Go Pro Camera" , amount: 134.50 , qty: 5 , total: 0.0 },
      { id: 3, cashAdvnaceId: 1, itemName: "Sony Bluetooth Earphones", amount: 34.99 , qty: 10 , total: 0.0, }
  },
  local!runningTotal: 0.0,
 
  a!formLayout(
    label: "Invoice Style",
    contents: {
      a!gridLayout(
        totalCount: count(local!invoice),
        headerCells: {
          a!gridLayoutHeaderCell(label: "Item" ),
          a!gridLayoutHeaderCell(label: "Amount", align: "RIGHT" ),
          a!gridLayoutHeaderCell(label: "Qty", align: "RIGHT" ),
          a!gridLayoutHeaderCell(label: "Total", align: "RIGHT" ),
          /* For the "Remove" column */
          a!gridLayoutHeaderCell(label: "" )
        },
        /* Only needed when some columns need to be narrow */
        columnConfigs: {
          a!gridLayoutColumnConfig(width: "DISTRIBUTE", weight:7 ),
          a!gridLayoutColumnConfig(width: "DISTRIBUTE", weight:2 ),
          a!gridLayoutColumnConfig(width: "DISTRIBUTE", weight:1 ),
          a!gridLayoutColumnConfig(width: "DISTRIBUTE", weight:2 ),
          a!gridLayoutColumnConfig(width: "ICON")
        },
        /*
        * a!forEach() will take local!employee data and used that data to loop through an
        * expression that creates each row.
        *
        * When modifying the recipe to work with your data, you only need to change:
        * 1.) the number of fields in each row
        * 2.) the types of fields for each column (i.e. a!textField() for text data elements)
        * 3.) the fv!item elements. For example fv!item.item would change to fv!item.yourdata
        */
        rows: a!forEach(
          items: local!invoice,
          expression: a!gridRowLayout(
            id: fv!index,
            contents: {

              /* For the Item Name Column*/
              a!textField(
                /* Labels are not visible in grid cells but are necessary to meet accessibility requirements */
                label: "item " & fv!index,
                value: fv!item.itemName,
                saveInto: fv!item.itemName,
                required: true
              ),
              /* For the Amount Column*/
              a!floatingPointField(
                label: "Amount " & fv!index,
                labelPosition: "ADJACENT",
                value: fv!item.amount,
                saveInto: fv!item.amount,
                refreshAfter: "UNFOCUS",
                validations: {},
                align: "RIGHT"
              ),
              /* For the Qty Column*/
              a!floatingPointField(
                label: "Qty " & fv!index,
                labelPosition: "ADJACENT",
                value: fv!item.qty,
                saveInto: fv!item.qty,
                refreshAfter: "UNFOCUS",
                validations: {},
                align: "RIGHT"
              ),
              /* For the Total Column*/
              a!floatingPointField(
                label: "Qty " & fv!index,
                labelPosition: "ADJACENT",
                value: fv!item.total,
                saveInto: fv!item.total,
                refreshAfter: "UNFOCUS",
                validations: {},
                align: "RIGHT"
              ),
              /* For the Removal Column*/
              a!imageField(
                label: "delete " & fv!index,
                images: a!documentImage(
                  document: a!iconIndicator("REMOVE"),
                  altText: "Remove Employee",
                  caption: "Remove " & fv!item.item & " " & fv!item.lastName,
                  link: a!dynamicLink(
                    value: fv!index,
                    saveInto: {
                      a!save(local!invoice, remove(local!invoice, save!value))
                    }
                  )
                ),
                size: "ICON"
              )
            }
          )
        ),
        addRowlink: a!dynamicLink(
          label: "Add a new line.",
          /*
           * For your use case, set the value to a blank instance of your CDT using
           * the type constructor, e.g. type!Employee(). Only specify the field
           * if you want to give it a default value e.g. startDate: today()+1.
           */
          value: {
            startDate: today() + 1
          },
          saveInto: {
            a!save(local!invoice, append(local!invoice, save!value))
          }
        )
      ),
      a!sectionLayout(
        label: "",
        contents: {
          a!columnsLayout(
            columns: {
              a!columnLayout(
                contents: {}
              ),
              a!columnLayout(
                contents: {}
              ),
              a!columnLayout(
                contents: {
                  a!floatingPointField(
                    label: "Total Amount",
                    labelPosition: "ADJACENT",
                    saveInto: {},
                    refreshAfter: "UNFOCUS",
                    validations: {},
                    align: "RIGHT"
                  )
                }
              )
            }
          )
        }
      )
    },
    buttons: a!buttonLayout(
      primaryButtons: a!buttonWidget(
        label: "Submit",
        submit: true
      )
    )
  )
)

 

Screenshot

-------------

  Discussion posts and replies are publicly visible