How to refresh dynamically a RecordType inside in an interface?

Certified Senior Developer

Hi,

Could you tell me how a filtered RecordType grid (placed inside an interface) can be refreshed please ?

My RecordType data are retrieved from the a!recordData() function, and is filtered on the field "deleted" (all rows are visible if delete = "false").

I have a button that calls an Expression Rule to update the underlying table to set the "deleted" field of the selected row to "true".

(I use the WriteToDataStoreEntity Smartservice).

After the table is updated in database, I have click to click on the "refresh" icon of the RecordType to see that all is working fine : the lines are hidded.

How would you refresh the RecordType, without a manual user action please ?

(I intentionnaly do not use any process model for this example)

  Discussion posts and replies are publicly visible

Parents
  • the best solution I can think is to use a local variable that refreshes

  • 0
    Certified Senior Developer
    in reply to ManuelHTG

    Thank you Manuel for your reply, but  a!recordData() is set to a local variable.

    But while this local variable is refreshed (with refreshvariable function), the RecordType is never refreshed.

    Am I missing something ?

  • 0
    Certified Lead Developer
    in reply to cedric01

    The only other way I'm used to is to build your own record filtering (which isn't very hard) and populate the grid using data pulled straight from a!queryEntity().  You give up some of the OOB "record list" functionality and gain more flexibility, including, i expect, the ability to have the grid automatically refresh after your deactivation has been fired.

  • 0
    Certified Senior Developer
    in reply to Mike Schmitt

    In our project, we have coded a lot of grids exactly like you've described it, but we still have a lot of RecordType grids, and these will probably remain like this.

    But thank you Mike, your feedback is great.

  • 0
    Appian Employee
    in reply to cedric01

    a!recordData() does not query the record type, but instead helps define the query for a grid. To query data from a record type, use a!queryRecordType(). As Mike has said, you can use a!recordData() directly in a!gridField() and then use the refresh parameters on gridField

  • 0
    Certified Senior Developer
    in reply to Danny Verb

    Thank you Danny, but I'm afraid that a!queryRecordType() does not work with a RecordType-based-grid.

    (I have already posted this issue in another post but never had a reply)

    Here is my complete code, I would really appreciate if you could tell me why this code does not work please :

    a!localVariables(
      local!selectedRows,
      local!selection,
      local!refreshCounter: 0,
      
      local!pagingInfo: a!pagingInfo(1, 10),
      local!data : a!queryRecordType(
        recordType: 'recordType!CJT_R_Vehicles',
        selection: {
          'recordType!CJT_R_Vehicles.fields.id',
          'recordType!CJT_R_Vehicles.fields.model',
          'recordType!CJT_R_Vehicles.fields.vin',
          'recordType!CJT_R_Vehicles.fields.isavailable',
          'recordType!CJT_R_Vehicles.fields.dateacquired',
          'recordType!CJT_R_Vehicles.fields.year',
          'recordType!CJT_R_Vehicles.fields.deleted',
        },
        filters: {
          a!queryFilter(
            field: 'recordType!CJT_R_Vehicles.fields.deleted',
            operator: "=",
            value: false
          )
        },
        pagingInfo: local!pagingInfo,
        fetchTotalCount: true
      ),
    
      a!formLayout(
        label: "Grid with RecordType",
        contents: {
          a!gridField(
            label: "Vehicles",
            labelPosition: "COLLAPSED",
            data: local!data,
            columns: {
              a!gridColumn(
                label: "Id",
                sortField: 'recordType!CJT_R_Vehicles.fields.id',
                value: fv!row['recordType!CJT_R_Vehicles.fields.id'],
                align: "END"
              ),
              a!gridColumn(
                label: "Make",
                sortField: 'recordType!CJT_R_Vehicles.fields.make',
                value: a!linkField(
                  links: {
                    a!recordLink(
                      label: fv!row['recordType!CJT_R_Vehicles.fields.make'],
                      recordType: 'recordType!CJT_R_Vehicles',
                      identifier: fv!identifier
                    )
                  }
                )
              ),
              a!gridColumn(
                label: "Model",
                sortField: 'recordType!CJT_R_Vehicles.fields.model',
                value: fv!row['recordType!CJT_R_Vehicles.fields.model']
              ),
              a!gridColumn(
                label: "Vin",
                sortField: 'recordType!CJT_R_Vehicles.fields.vin',
                value: fv!row['recordType!CJT_R_Vehicles.fields.vin']
              ),
              a!gridColumn(
                label: "Isavailable",
                sortField: 'recordType!CJT_R_Vehicles.fields.isavailable',
                value: fv!row['recordType!CJT_R_Vehicles.fields.isavailable']
              ),
              a!gridColumn(
                label: "Dateacquired",
                sortField: 'recordType!CJT_R_Vehicles.fields.dateacquired',
                value: fv!row['recordType!CJT_R_Vehicles.fields.dateacquired'],
                align: "END"
              ),
              a!gridColumn(
                label: "Year",
                sortField: 'recordType!CJT_R_Vehicles.fields.year',
                value: fv!row['recordType!CJT_R_Vehicles.fields.year'],
                align: "END"
              ),
              a!gridColumn(
                label: "Deleted",
                sortField: 'recordType!CJT_R_Vehicles.fields.deleted',
                value: fv!row['recordType!CJT_R_Vehicles.fields.deleted']
                align: "END"
              )
            },
    
            initialSorts: {
              a!sortInfo(
                field: 'recordType!CJT_R_Vehicles.fields.id'
              )
            },
            showWhen: true,
            selectable: true,
            selectionStyle: "ROW_HIGHLIGHT",
            selectionValue: local!selection,
            
            selectionsaveInto: {
              a!save(local!selectedRows, index(fv!selectedRows, length(fv!selectedRows), null)),
              a!save(local!selection, index(save!value, length(save!value), null)),
              a!save(ri!selectedVehicle,
                index(
                  fv!selectedRows,
                  length(fv!selectedRows),
                  null
                )
              )
            },
            validations: {},
            refreshAfter: "RECORD_ACTION",
            userFilters: {
            },
            showSearchBox: true,
            showRefreshButton: true,
            showExportButton: false,
            recordActions: {}
          )
        },
        buttons: a!buttonLayout(
          secondaryButtons: {
            a!buttonWidget(
              label: "Delete selected",
              saveInto: {
                a!save(
                  ri!selectedVehicle.deleted, true
                ),
                rule!CJT_ER_SaveVehicle(
                  vehicle: ri!selectedVehicle,
                  refreshCounter: local!refreshCounter
                )
              },
              submit: false,
              style: "PRIMARY",
              showWhen: true,
              confirmMessage: "Do you confirm deactivating this row?",
              disabled: rule!SHARED_IsNullOrEmpty(ri!selectedVehicle)
            )
          }
        )
      )
    )

    That code above throws this error :

    Could not display interface. Please check definition and inputs.
    Interface Definition: Expression evaluation error at function a!gridField [line 53]: A grid component [label=“Vehicles”] has an invalid value for “showSearchBox”. “userFilters” and “showSearchBox” may only be specified when “data” is sourced from a Record Type.

  • 0
    Certified Lead Developer
    in reply to Danny Verb

    - a!queryRecordType() doesn't cause the grid to invoke the "OOB record list" features though, right?  As far as I understood, the only way to do that was to use a!recordData().  And of course, due to that and the clarificaton you provided, it doesn't seem like there's actually a way to cause the "OOB-style" record list grid to be refreshed via external input - can you confirm that this is the expected behavior?  It seems artificially limiting, though I could understand if it's not possible due to stuff on the back-end.

  • @cedric I recommend placing a!recordData() in the data parameter for a!gridField instead of using a local variable. Using the refresh parameters on the grid such as refreshOnVarChange data can be refreshed due to external input

  • 0
    Certified Lead Developer
    in reply to Danny Verb

    For clarification, did you actually mean to say "can't be refreshed due to external input"?

  • I think what Danny is saying is that there is a parameter directly on the grid that allows you to refresh based on a referenced variable change - in cases where a!recordData() is used, you can utilize these parameters on the grid to provide the same behavior as you would get from a!refreshVariable().

    For instance, I think if you try adding this line within your grid it should work:

    refreshOnVarChange: {ri!selectedvehicle.deleted}

  • 0
    Certified Lead Developer
    in reply to Peter Lewis

    Thanks Peter - I actually hadn't noticed that a!gridField() had gotten "refreshOnVarChange" etc parameters.  i believe this should answer it for you.  I've tried in my test interface and it does successfully refresh now on increment of the refresh counter.

  • 0
    Certified Senior Developer
    in reply to Mike Schmitt

    That's great, it works well! like you Mike, I did not know that the Gridfield had such a refresh parameter.

    Thank you Mike, Peter, Danny for your help :-)

Reply Children
No Data