Editable Grid with dateField not updating due to index.

Certified Senior Developer

I am configuring an editable grid. I have a couple readOnly fields that get populated based on what the user selects in one of the other editable fields.

In this specific case, if the user selects a specific account number (the dropDownField(), the textfield above this gets updated. This field updates correctly. However, I get an error with that same if() statement for the dateField. How do I resolve this. See attached for code snippet and error.

  Discussion posts and replies are publicly visible

Parents
  • The error suggests that your fv!item object does not have a property called 'effectiveDate' - are you able to share the data type that is associated with an instance of fv!item?

  • 0
    Certified Lead Developer
    in reply to Stewart Burchell

    It could also be ri!selectedAccount_cdt that doesn't have the 'effectiveDate' property - in fact that would be my first guess over fv!item based on the current setup.

  • Doh! That'll teach me to read the code properly...yes, I agree..

  • 0
    Certified Senior Developer
    in reply to Mike Schmitt

    Good catch Mike! I should have had ri!newArngmt_cdt.effectiveDate! Once I changed that - it worked. THANK YOU!!!

    a!dateField(
    label: "Effective Date "& fv!index,
    value: if(fv!item.accountNum = ri!newAccount_cdt.accountNum,
    today(),
    ri!newArngmt_cdt.effectiveDate),
    saveInto: fv!item.effectiveDate,
    readOnly: true
    )

    One other question on this - how do I get the data displayed in the editable grid to sort by the id? 

  • 0
    Certified Lead Developer
    in reply to judym598
    how do I get the data displayed in the editable grid to sort

    Effectively the only way I'd recommend attempting to sort an editable grid is to sort the data ahead of time - if you're querying the underlying data on-form, for example, just sort by whichever field you want in the initial query.  If you're using a passed-in rule input, then you could attempt to massage the data before rendering it on the grid, but this gets super messy and cumbersome; if at all possible i'd recommend editing the process model to either query the data in a sorted manner or perhaps sort it for you before entering the task.  Again this all depends on how and when you're querying/assembling the data used for the grid.

  • 0
    Certified Senior Developer
    in reply to Mike Schmitt

    I was afraid you'd say that. What I'm doing is 

    1) Displaying data in a read only grid (from an expression rule the uses an a!queryEntity) - and allowing the user to select the items to edit which then gets stored into another rule input. 

    2) The editable grid then displays with the data selected. if the user selects them in order - they will display correctly, but if the user selects the bottom one first, then the 2nd one - they will display in the order selected on the first grid.

    I have to keep the data 'local' until the updates are approved - before committing the changes to the database. Is there a way to sort the data in the rule input that is selected in the first grid?

  • 0
    Certified Lead Developer
    in reply to judym598

    How are you currently assembling the array of data used for the editable grid, based on the user's selections from the read-only grid?  Mind sharing a snippet of the relevant code?  I'd guess you could likely keep the editable lines in the original order pretty easily but again it sorta depends on the specifics.

  • 0
    Certified Senior Developer
    in reply to Mike Schmitt

    Please see the attached. Note that it is not complete. I've added comments at the top to explain what my intentions are.

    /* I intend on having a condition on when the grids display. upon entering this form,
    the user will see the read only grid to make selections. Then - I plan on adding a button
    that will switch the view to the editable grid. Then when updates are complete, a button 
    will display to submit the changes - sent to a reviewer for approval....)*/
    
      a!localVariables(
        /* This variable is used to persist the checkbox on selected items by holding the identifiers of the selected rows. */
        local!selection,
        /* This variable is used to pass the full rows of data on the selected items out of this interface, such as to a process model. 
            In this case, it passes values to ri!newArngmt_cdt*/
        local!selectedRows,
        /* This variable is used to pass the updates made to ri!newArngmt_cdt to ri!updatedArngmt_cdt*/
        local!updatedArngmt: ri!newArngmt_cdt,
        {
          a!columnsLayout(
            columns:{
              a!columnLayout(
                contents:{
                  a!gridField(
                    label: "Update Accounts Associated with this Customer Account",
                    instructions: "Check the box next to accounts that should be updated to new account. Once selected, you will be able to edit.",
                    data: rule!esc_getArngmtRows(ri!selectedAccount_cdt.fiId, ri!selectedAccount_cdt.accountNum).data,
                    columns: {
                      a!gridColumn(
                        label: "RY",
                        sortField: "ryId",
                        value: fv!row.ryID
                      ),
                      a!gridColumn(
                        label: "Routing Number",
                        sortField: "fiId",
                        value: fv!row.fiId
                      ),
                      a!gridColumn(
                        label: "Account Number",
                        sortField: "accountNum",
                        value: fv!row.accountNum
                      ),
                      a!gridColumn(
                        label: "Effective Date",
                        sortField: "effectiveDate",
                        value: fv!row.effectiveDate,
                        align: "END"
                      )
                    },
                    pageSize: 6,
                    selectable: true,
                    selectionValue: local!selection,
                    selectionSaveInto: {
                      local!selection,
                      /* This save adds the full rows of data for items selected in the most recent user interaction to local!selectedRows. */
                      a!save(local!selectedRows, append(local!selectedRows, fv!selectedRows)),
                      /* This save removes the full rows of data for items deselected in the most recent user interaction to local!selectedRows. */
                      a!save(local!selectedRows, difference(local!selectedRows, fv!deselectedRows)),
                      a!save(ri!newArngmt_cdt, local!selectedRows)
                    }
                  ),
                  a!sectionLayout(
                    label: "Customer Accounts to be Updated",
                    contents: {
                      a!gridLayout(
                        label: "",
                        labelPosition: "ABOVE",
                        instructions: "Make the necessary changes to selected accounts associated to their respective reinsurance years",
                        totalcount: count(local!updatedArngmt),
                        emptygridmessage: "No accounts selected to update.",
                        headerCells: {
                          a!gridLayoutHeaderCell(label: "RY" ),
                          a!gridLayoutHeaderCell(label: "Routing Number" ),
                          a!gridLayoutHeaderCell(label: "Account Number" ),
                          a!gridLayoutHeaderCell(label: "Effective Date", align: "RIGHT" )
                          },
                        /* Only needed when some columns need to be narrow */
                        columnConfigs: {
                          a!gridLayoutColumnConfig(width: "DISTRIBUTE", weight:1 ),
                          a!gridLayoutColumnConfig(width: "DISTRIBUTE", weight:1 ),
                          a!gridLayoutColumnConfig(width: "DISTRIBUTE", weight:3 ),
                          a!gridLayoutColumnConfig(width: "DISTRIBUTE", weight:2 )
                          },
                          rows: a!forEach(
                            items: local!updatedArngmt,
                            expression: a!gridRowLayout(
                              id: fv!index,
                              contents: {
                                a!textField(
                                  label: "RY "& fv!index,
                                  value: fv!item.ryId,
                                  readOnly: true()
                                ),
                                a!textField(
                                  label: "FiID "& fv!index,
                                  value: if(fv!item.accountNum = ri!newAccount_cdt.accountNum,
                                         ri!newAccount_cdt.fiId,
                                         ri!selectedAccount_cdt.fiId
                                         ),
                                  saveInto: fv!item.fiId,
                                  readOnly: true
                                ),
                                a!dropdownField(
                                  label: "Account Number "&fv!index,
                                  choiceLabels: {ri!selectedAccount_cdt.accountNum, ri!newAccount_cdt.accountnum},
                                  choiceValues: {ri!selectedAccount_cdt.accountNum, ri!newAccount_cdt.accountnum},
                                  value: fv!item.accountNum,
                                  saveInto: fv!item.accountNum,
                                  required: true()
                                ),
                                a!dateField(
                                  label: "Effective Date "& fv!index,
                                  value: if(fv!item.accountNum = ri!newAccount_cdt.accountNum,
                                  today(),
                                  ri!newArngmt_cdt.effectiveDate),
                                  saveInto: fv!item.effectiveDate,
                                  readOnly:  true
                                )
                              }
                            )
                          ),
                        selectionvalue: ri!newArngmt_cdt,
                        selectionSaveInto: local!updatedArngmt,
                        validations: {},
                        shadeAlternateRows: true
                      )
                    }
                  )
                }
              )
            }
          )
        }
      )
    

  • 0
    Certified Lead Developer
    in reply to judym598

    That's a tricky one.  Since you're querying the data for the read-only grid directly within the read-only grid, the one idea i had is basically out the window.  In that, every time the user did a selection, you'd build the array of selected row data by iterating over the original data set and adding every member that corresponded with the index of the new selection (keeping the ordering consistent regardless of additions or deletions).

  • 0
    Certified Senior Developer
    in reply to Mike Schmitt

    Wow....are there instructions on how to do that in the documentation? I take it there's no way to 'sort' on a local!variable..

  • 0
    Certified Lead Developer
    in reply to judym598

    Basically I just mean moving the "data:" field from your read-only grid into a local variable above the grid definition.  I could give you pointers on executing the save in an order-preserving manner if you got that part taken care of.

    Alternatively, the one supported method for sorting a CDT (i.e. in your grid's saveInto), would be to call toDataSubset on it and pass in paging info with sorting on the column you'd want to sort by.  The result of this would be that the ri!newArngmt_cdt data would be sorted by that column regardless of the selection order OR current sorting of the paging grid (which i suppose is probably what you want).

    For this, and bear with my guesswork here, but I assume you could replace this

    a!save(ri!newArngmt_cdt, local!selectedRows)

    with something like this (assuming for example's sake that you want it to be sorted on "accountNum") --

    a!save(
      ri!newArngmt_cdt,
      todatasubset(
        local!selectedRows,
        a!pagingInfo(
          startIndex: 1,
          batchSize: -1,
          sort: a!sortInfo(
            field: "accountNum",
            ascending: true()
          )
        )
      ).data
    )

  • 0
    Certified Senior Developer
    in reply to Mike Schmitt

    Thank you Mike. I think that will work. I will update this thread on Monday if it does - maybe it will help others out. 

Reply Children
  • 0
    Certified Senior Developer
    in reply to judym598

    Got another question here on my date field. I don't want the user to edit the value (which i why it is readOnly), but I want it updated if the user changes the account number to 'today()'. What I have below displays the correct date in the form but it does not save it to the local variable - therefore, it does not get saved once I leave the form. How do I get the local variable to update? I tried using a!save (see last line) to force it to save to the local variable, but it's not. 

    a!dateField(
      label: "Effective Date "& fv!index,
      value: if(fv!item.accountNum = ri!newAccount_cdt.accountNum, today(), ri!newArngmt_cdt.effectiveDate),
      saveInto: fv!item.effectiveDate,
      readOnly: true
    )

    Tried this for the saveInto - but it didn't work:

    saveInto: a!save(fv!item.effectiveDate,local!newArngmt.effectiveDate)

  • 0
    Certified Lead Developer
    in reply to judym598

    Hi - As I mentioned in an earlier reply (which i think you may have missed), having a "saveInto" in a Read Only field will literally do nothing, as the saveInto parameter only executes upon user interaction with that field.  You need to add your extra save information into the saveInto parameter of the Account Number field, if it's by interaction with that field that you want the date in question to get updated.