Editable Data Grid Error - Add/Remove rows from data grid whose data is from a query

Dear All,

I created an editable datagrid from sample code found from the SAIL Recipes and it fetches the data fine, and I am happy about that.

However, when I delete a row or add a row to my grid I get the following errors -

In Design Time, I get:
Could not display interface. Please check definition and inputs.
Interface Definition: Expression evaluation error: An error occurred while executing a save: Expression evaluation error at function 'remove' [line 309]: Invalid index (3) for list: valid range is 1...1


During Runtime, I get:
Error Evaluating UI Expression
Expression evaluation error in rule 'cshv_initiator_rework' at function a!forEach [line 207]: Error in a!forEach() expression during iteration 1: Expression evaluation error at function a!textField [line 213]: Invalid index: Cannot index property 'itemName' of type Text into type DataSubset

Here below is the SAIL code for my editable grid.  Can some find where the problem might lie?

Thanks

---

local!lineItemsPagingInfo: a!pagingInfo(
    startIndex: 1,
    batchSize: 10
    ),
 
local!input: a!queryEntity(
  entity:cons!CSHV_LINE_ITEM_CDT,
  query:a!query(
 selection: a!querySelection(columns: {
   a!queryColumn(field: "itemName"),
   a!queryColumn(field: "amount"),
   a!queryColumn(field: "qty"),
   a!queryColumn(field: "total")
 }),
  filter: a!queryFilter(
 field: "cashAdvnaceId.id",
 operator: "=",
 value: ri!CashAdvanceRequestData.id
  ),
  PagingInfo: local!lineItemsPagingInfo
  )
),
 
  local!gridSelection: a!gridSelection(
  selected: {},
  pagingInfo: a!pagingInfo(
    startIndex: 1,
    batchSize: 10,
    sort: a!sortInfo(
      field: "timeStamp",
      ascending: false
    )
  )
),

a!gridLayout(
  totalCount: count(
 local!lineItemsPagingInfo
  ),
  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"
 )
  },
  rows: a!forEach(
 items: local!input,
 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,
   if(
     rule!APN_isBlank(
    fv!item.qty
     ),
     "",
     a!save(
    fv!item.total,
    product(
      fv!item.amount,
      fv!item.qty
    )
     )
   )
    },
    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,
   if(
     rule!APN_isBlank(
    fv!item.amount
     ),
     "",
     a!save(
    fv!item.total,
    product(
      fv!item.amount,
      fv!item.qty
    )
     )
   )
    },
    refreshAfter: "UNFOCUS",
    validations: {},
    align: "RIGHT"
  ),
  /* For the Total Column*/
  a!floatingPointField(
    label: "Total " & fv!index,
    labelPosition: "ADJACENT",
   
    value: if(
   or(
     rule!APN_isBlank(
    fv!item.amount
     ),
     rule!APN_isBlank(
    fv!item.qty
     )
   ),
   fv!item.total,
   product(
     fv!item.amount,
     fv!item.qty
   )
    ),
    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 Line Item",
   caption: "Remove " & fv!item.item & " " & fv!item.lastName,
   link: a!dynamicLink(
     value: fv!index,
     saveInto: {
    a!save(
      local!input,
      remove(
     local!input,
     save!value
      )
    )
     }
   )
    ),
    size: "ICON"
  )
   }
 )
  ),
  addRowlink: a!dynamicLink(
 label: "Add a new line.",
 saveInto: {
   a!save(
  local!input,
  append(
    local!input,
    save!value
  )
   )
 }
  )
)

  Discussion posts and replies are publicly visible

Parents
  • Hi

    Change -->rows: a!forEach(
    items: local!input.. to
    --> rows: a!forEach(
    items: local!input.data...
  • 0
    A Score Level 1
    in reply to ankitab0001
    Thanks Ankita,

    I made the change to input.data but then the rows now show as blank rows (without any data in them). Secondly, now, I get the error below when I try to edit the Amount, Qty or Total columns. These three columns are used in calculations.

    Could not display interface. Please check definition and inputs.
    Interface Definition: Expression evaluation error: An error occurred while executing a save: java.lang.IllegalArgumentException: Invalid index: Cannot index property 'amount' into type List of Null
  • Ok,

    seems the local!input type is anyType, try to convert into proper CDT type.

    local!input : cast(
    type!CSHV_Request_Data,
    <query entity>
    )
  • Thanks,

    Here is the new block of code:
    addRowlink: a!dynamicLink(
    label: "Add a new line.",
    value: cast(type!CSHV_Request_Data, local!input),
    saveInto: {
    a!save(
    local!input,
    append(
    local!input,
    save!value
    )
    )
    }
    )

    However, now, I get this error:
    Could not display interface. Please check definition and inputs.
    Interface Definition: Expression evaluation error at function a!forEach [line 212]: Error in a!forEach() expression during iteration 4: Expression evaluation error at function a!documentImage [line 308]: Invalid index: Cannot index property 'item' of type Text into type CSHV_Request_Data
  • The cast function is needed in addRowLink but u need to cast an empty or a null value as suggested by Vinay as you want to add a new row and request the data to be entered by the end user. Also you would need to cast local parameter local!input to the same type. Could you please check if item is one of the properties in your CDT or please share what do you need to display as the caption in the "Remove" column when you hover on the icon or image?
  • Hi Susan,

    Please try the below code snippet for addRowlink,

    addRowlink: a!dynamicLink(
      label: "Add a new line.",
      value: 'type!{urn:com:appian:types/CSHV}CSHV_Request_Data'(
        itemName: null,
        qty: null,
        amount: null,
        total: null
      ),
      saveInto: {
        a!save(
          local!input,
          append(
            local!input,
            save!value
          )
        )
      }
    )

     

    Thanks,

    Hema

  • 0
    A Score Level 1
    in reply to Hema
    Hi All,

    Thanks so much for taking the time to look at this issue and offering your support.

    I have incorporated most of your suggestions and couldn't incorporate one because it broke the page. However, at this point, I am getting the following error whenever I try to remove a row.

    Could not display interface. Please check definition and inputs.
    Interface Definition: Expression evaluation error at function a!forEach [line 211]: Error in a!forEach() expression during iteration 3: Expression evaluation error at function a!documentImage [line 307]: Invalid index: Cannot index property 'item' of type Text into type CSHV_Request_Data

    At this point, I think the best thing is to put here the entire code for the interface so that if anyone has a chance, they can take a look from top to bottom.

    Thanks

    ---

    load(

    local!lineItemsPagingInfo: a!pagingInfo(
    startIndex: 1,
    batchSize: 10
    ),

    local!input: a!queryEntity(
    entity:cons!CSHV_LINE_ITEM_CDT,
    query:a!query(
    selection: a!querySelection(columns: {
    a!queryColumn(field: "itemName"),
    a!queryColumn(field: "amount"),
    a!queryColumn(field: "qty"),
    a!queryColumn(field: "total")
    }),
    filter: a!queryFilter(
    field: "cashAdvnaceId.id",
    operator: "=",
    value: ri!CashAdvanceRequestData.id
    ),
    PagingInfo: local!lineItemsPagingInfo
    )
    ).data,

    local!gridSelection: a!gridSelection(
    selected: {},
    pagingInfo: a!pagingInfo(
    startIndex: 1,
    batchSize: 10,
    sort: a!sortInfo(
    field: "timeStamp",
    ascending: false
    )
    )
    ),

    /* Use query entity to get data to local!input*/
    with(

    local!datasubset: a!queryEntity(
    entity:cons!CSHV_COMMENT_CDT,
    query:a!query(
    selection: a!querySelection(columns: {
    a!queryColumn(field: "author"),
    a!queryColumn(field: "status"),
    a!queryColumn(field: "timeStamp"),
    a!queryColumn(field: "comment")
    }),
    filter: a!queryFilter(
    field: "cashAdvanceId.id",
    operator: "=",
    value: ri!CashAdvanceRequestData.id
    ),
    pagingInfo: local!gridSelection.pagingInfo
    )
    ),



    a!formLayout(
    label: "",
    instructions: "",
    contents: {



    a!imageField(
    label: "",
    labelPosition: "ABOVE",
    images: {
    a!documentImage(
    document: cons!CSHV_IMAGE_VIEW_TOP
    )
    },
    size: "FIT",
    isThumbnail: false,
    style: "STANDARD"
    ) ,
    a!sectionLayout(
    label: "Cash Advance Application",
    contents: {
    a!columnsLayout(
    columns: {
    a!columnLayout(
    contents: {
    a!textField(
    label: "Initiator Re-work Task",
    labelPosition: "ABOVE",
    saveInto: {},
    refreshAfter: "UNFOCUS",
    readonly: true,
    disabled: false,
    validations: {}
    )
    }
    ),
    a!columnLayout(
    contents: {}
    ),
    a!columnLayout(
    contents: {}
    )
    }
    )
    }
    ),


    a!sectionLayout(
    label: "",
    contents: {
    a!columnsLayout(
    columns: {
    a!columnLayout(
    contents: {
    a!textField(
    label: "Requester Name",
    labelPosition: "ABOVE",
    value: ri!CashAdvanceRequestData.requester,
    saveInto: ri!CashAdvanceRequestData.requester,
    refreshAfter: "UNFOCUS",
    validations: {}
    )
    }
    ),
    a!columnLayout(
    contents: {
    a!textField(
    label: "Request Category",
    labelPosition: "ABOVE",
    value: ri!CashAdvanceRequestData.category,
    saveInto: ri!CashAdvanceRequestData.category,
    refreshAfter: "UNFOCUS",
    validations: {}
    )
    }
    ),
    a!columnLayout(
    contents: {
    a!textField(
    label: "Department",
    labelPosition: "ABOVE",
    value: ri!CashAdvanceRequestData.department,
    saveInto: ri!CashAdvanceRequestData.department,
    refreshAfter: "UNFOCUS",
    validations: {}
    )
    }
    )
    }
    )
    }
    ),


    /* Start Editing Grid */
    a!gridLayout(
    totalCount: count(
    local!lineItemsPagingInfo
    ),
    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"
    )
    },
    rows: a!forEach(
    items: local!input,
    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,
    if(
    rule!APN_isBlank(
    fv!item.qty
    ),
    "",
    a!save(
    fv!item.total,
    product(
    fv!item.amount,
    fv!item.qty
    )
    )
    )
    },
    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,
    if(
    rule!APN_isBlank(
    fv!item.amount
    ),
    "",
    a!save(
    fv!item.total,
    product(
    fv!item.amount,
    fv!item.qty
    )
    )
    )
    },
    refreshAfter: "UNFOCUS",
    validations: {},
    align: "RIGHT"
    ),
    /* For the Total Column*/
    a!floatingPointField(
    label: "Total " & fv!index,
    labelPosition: "ADJACENT",

    value: if(
    or(
    rule!APN_isBlank(
    fv!item.amount
    ),
    rule!APN_isBlank(
    fv!item.qty
    )
    ),
    fv!item.total,
    product(
    fv!item.amount,
    fv!item.qty
    )
    ),
    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 Line Item",
    caption: "Remove " & fv!item.item & " " & fv!item.lastName,
    link: a!dynamicLink(
    value: fv!index,
    saveInto: {
    a!save(
    local!input,
    remove(
    local!input,
    save!value
    )
    )
    }
    )
    ),
    size: "ICON"
    )
    }
    )
    ),


    addRowlink: a!dynamicLink(
    label: "Add a new line.",
    value: 'type!{urn:com:appian:types/CSHV}CSHV_Request_Data'(
    itemName: NULL,
    qty: NULL,
    amount: NULL,
    total: NULL
    ),
    saveInto: {
    a!save(
    local!input,
    append(
    local!input,
    save!value
    )
    )
    }
    )

    ),

    /* End Editing Grid */


    a!sectionLayout(
    label: "",
    contents: {
    a!columnsLayout(
    columns: {
    a!columnLayout(
    contents: {
    a!fileUploadField(
    label: "Supporting Documents",
    labelPosition: "ABOVE",
    maxselections: 1,
    value: ri!CashAdvanceRequestData.attachment,
    saveInto: ri!CashAdvanceRequestData.attachment,
    validations: {}
    )
    }
    ),
    a!columnLayout(
    contents: {}
    ),
    a!columnLayout(
    contents: {
    a!floatingPointField(
    label: "Total Amount",
    labelPosition: "ADJACENT",
    value: sum(
    a!forEach(
    items: local!input,
    expression: if(
    or(
    rule!APN_isBlank(
    fv!item.amount
    ),
    rule!APN_isBlank(
    fv!item.qty
    )
    ),
    fv!item.total,
    product(
    fv!item.amount,
    fv!item.qty
    )
    )
    )
    ),
    saveInto: ri!CashAdvanceRequestData.totalApproved,
    refreshAfter: "UNFOCUS",
    readOnly: true,
    validations: {},
    align: "RIGHT"
    )
    }
    )
    }
    )
    }
    ),
    a!sectionLayout(
    label: "",
    contents: {

    a!gridField(
    label: "Comments",
    totalCount: local!datasubset.totalCount,
    columns: {
    a!gridTextColumn(label: "Commenter", field: "author", data: index(local!datasubset.data, "author" , {})),
    a!gridTextColumn(label: "Status", field: "status", data: index(local!datasubset.data, "status" , {})),
    a!gridTextColumn(label: "Date & Time", field: "timeStamp", data: index(local!datasubset.data, "timeStamp" , {})),
    a!gridTextColumn(label: "Comment", field: "comment", data: left(index(local!datasubset.data, "comment" , {}), 40))
    },
    identifiers: local!datasubset.identifiers,
    value: local!gridSelection,
    saveInto: {
    local!gridSelection
    },
    selection: true
    ),

    a!textField(
    label: "",
    value: if(
    length(
    local!gridSelection.selected
    ) <> 1,
    "Select a comment row to open the full comment text.",
    index(
    index(local!datasubset.data, "comment", null),
    wherecontains(
    local!gridSelection.selected,
    local!datasubset.identifiers
    )
    )
    ),
    readOnly: true
    )

    }
    ),
    a!paragraphField(
    label: "Re-work Comment",
    labelPosition: "ABOVE",
    value: ri!CashAdvanceRequestData.justification,
    saveInto: ri!CashAdvanceRequestData.justification,
    refreshAfter: "UNFOCUS",
    required: true,
    height: "MEDIUM",
    validations: {}
    )
    },
    buttons: a!buttonLayout(
    primaryButtons: a!buttonWidget(
    label: "Submit",
    value: "Submit",
    saveInto: {
    a!save(
    ri!input,
    local!input
    ),
    a!forEach(
    items: ri!input,
    expression: a!save(
    fv!item.total,
    if(
    or(
    rule!APN_isBlank(
    fv!item.amount
    ),
    rule!APN_isBlank(
    fv!item.qty
    )
    ),
    fv!item.total,
    product(
    fv!item.amount,
    fv!item.qty
    )
    )
    )
    ),
    a!save(ri!CashAdvanceRequestData.requester, loggedinuser()),
    a!save(ri!CashAdvanceRequestData.totalApproved,
    sum(
    a!forEach(
    items: local!input,
    expression: if(
    or(
    rule!APN_isBlank(
    fv!item.amount
    ),
    rule!APN_isBlank(
    fv!item.qty
    )
    ),
    fv!item.total,
    product(
    fv!item.amount,
    fv!item.qty
    )
    )
    )
    )
    ),
    a!save(ri!CashAdvanceRequestData.currentStatus, "Initiated")
    },
    submit: true
    )
    )
    )
    )
    )
  • Hi Susan,

    a!imageField(
    label: "delete " & fv!index,
    images: a!documentImage(
    document: a!iconIndicator(
    "REMOVE"
    ),
    altText: "Remove Line Item",
    caption: "Remove " & fv!item.item & " " & fv!item.lastName,
    link: a!dynamicLink(
    value: fv!index,
    saveInto: {
    a!save(
    local!input,
    remove(
    local!input,
    save!value
    )
    )
    }
    )
    ),
    size: "ICON"
    )
    }
    )
    )

    In the above code, for the attribute 'caption', fv! Item.item is configured. I guess it should be fv!item.itemName

    Hope it helps!!!

    Thanks,
    Hema
  • Also, verify if fv!item.lastName is the correct definition as I am not able to find any field of Cdt in the above code as lastName.

    Thanks,
    Hema
  • 0
    A Score Level 1
    in reply to Hema
    Hi Hema,

    Thanks!

    This absolutely nailed it.

    Have a great day.
  • 0
    A Score Level 1
    in reply to Hema
    Just one last matter on this issue. I have defined a rule input for this interface and named it input, with data type CSHV_Request_Data (array) and I am expecting the grid rows to get updated into this rule input but this is not happening. Is there anything in the code that can suggest why ri!input is not getting populated with the grid rows?

    Thanks
  • 0
    A Score Level 1
    in reply to susana197
    Okay,

    I just solved the last issue with - a!save(ri!input, local!input)

    Thanks!
Reply Children
No Data