Hi!
I have an issue with refreshing a page. I've got a read-only grid and a delete button. After I choose some of the rows a press delete, which launches "a!startProcess" function; the problem is that I don't know how to refresh or redirect in that case. I have no rule inputs or variables...
Discussion posts and replies are publicly visible
a!startProcess has the onSuccess parameter. This is evaluated as the process is started, or, when activity chaining is enabled, at the end of that chain. Now you can refresh the data in a a!save(), added to onSuccess.
The problem is that the data from the grid is obtained via a query. I tried to set parameter "refreshOnVarChanged" to local!customerIDs (which contains an array of ids of all selected rows). When I press the button I trigger the following function:
saveInto: a!startProcess( cons!CD_DELETE_CUSTOMER_DETAILS, {customerIDs: local!customerIDs}, a!save(local!customerIDs, null) )
but it won't reload the data in the grid, it only unchecks the checkboxes near the deleted rows.
As Stefan mentioned, you need to be using the onSuccess parameter of the startProcess() call to do that save - the way you have it set up now, you're nulling out the customerIds too early, and any refresh that may have happened due to that change will have already happened before any changes caused by the process which you might want refreshed in your local data.
Moving the "a!save(local!customerIDs, null())" to "onSuccess" might work just on its own. But for code clarity, one trick I usually do is to delcare a separate variable i.e. "local!refreshCounter: 0", and then in my "onSuccess", i'll overwrite it with "local!refreshCounter + 1". Then just add that to the "refershOnVarChanged" list wherever needed.
I also use a local!refreshCounter in these cases. The alternative is, to repeat the query inside of onSuccess. But this is duplicate code ...
But it's already in "onSuccess", I just skipped the parameter name. Adding the parameter names didn't change anything, I still get only checkboxes refreshed.
I tried to sutitute it with refreshcounter, but it still won't succeed...
I'll show all the code if needed:
a!localVariables( local!searchProvince: null, local!searchLastName: null, local!searchPhoneNumber: null, local!customerIDs: null, { a!columnsLayout( columns: { a!columnLayout( contents: { a!textField( label: "Filter province", labelPosition: "ABOVE", placeholder: "-- Enter a province--", value: local!searchProvince, saveInto: local!searchProvince, refreshAfter: "UNFOCUS", validations: {} ) } ), a!columnLayout( contents: { a!textField( label: "Filter Last Name", labelPosition: "ABOVE", placeholder: "-- Enter a last name --", value: local!searchLastName, saveInto: local!searchLastName, refreshAfter: "UNFOCUS", validations: {} ) } ), a!columnLayout( contents: { a!textField( label: "Filter Phone Number", labelPosition: "ABOVE", placeholder: "-- Enter a phone number --", value: local!searchPhoneNumber, saveInto: local!searchPhoneNumber, refreshAfter: "UNFOCUS", validations: {} ) } ) } ), a!gridField( label: "Customer Details", labelPosition: "ABOVE", data: a!queryEntity( entity: cons!CD_CUSTOMERDETAILS_DSE, query: a!query( logicalExpression: a!queryLogicalExpression( operator: "AND", filters: { a!queryFilter( field: "province", operator: "includes", value: local!searchProvince ), a!queryFilter( field: "lastName", operator: "includes", value: local!searchLastName ), a!queryFilter( field: "phoneNumber", operator: "=", value: local!searchPhoneNumber ) }, ignoreFiltersWithEmptyValues: true ), pagingInfo: fv!pagingInfo ), fetchTotalCount: true ), columns: { a!gridColumn( label: "Customer ID", sortField: "customerID", value: fv!row.customerID, align: "END" ), a!gridColumn( label: "First Name", sortField: "firstName", value: fv!row.firstName ), a!gridColumn( label: "Last Name", sortField: "lastName", value: fv!row.lastName ), a!gridColumn( label: "Street Address", sortField: "streetAddress", value: fv!row.streetAddress ), a!gridColumn( label: "City", sortField: "city", value: fv!row.city ), a!gridColumn( label: "Province", sortField: "province", value: fv!row.province ), a!gridColumn( label: "Zip Code", sortField: "zipCode", value: fv!row.zipCode ), a!gridColumn( label: "Phone Number", sortField: "phoneNumber", value: fv!row.phoneNumber ), a!gridColumn( label: "Email", sortField: "email", value: fv!row.email ), a!gridColumn( label: "Heard About Us From", sortField: "heardAboutUsFrom", value: fv!row.heardAboutUsFrom ), a!gridColumn( label: "Feedback", sortField: "feedback", value: fv!row.feedback ), a!gridColumn( label: "Suggestions", sortField: "suggestions", value: fv!row.suggestions ), a!gridColumn( label: "Would Recommend Us", sortField: "wouldRecommendUs", value: fv!row.wouldRecommendUs ) }, initialSorts: a!sortInfo( field: "lastName", ascending: true ), selectable: true, selectionValue: local!customerIDs, selectionSaveInto: local!customerIDs, validations: {}, refreshOnVarChange: local!customerIDs ), a!buttonArrayLayout( buttons: { a!buttonWidget( label: "Delete", saveInto: a!startProcess( processModel: cons!CD_DELETE_CUSTOMER_DETAILS, processParameters: {customerIDs: local!customerIDs}, onSuccess: a!save(local!customerIDs, null) ), submit: true, style: "DESTRUCTIVE", validate: true ) }, align: "END" )})
FYI when posting any code like this (especially anything longer than maybe 5 lines or so), it'd be helpful from both a readability perspective (as well as a "not making the post impossible to scroll" perspective) to use a Code Box, right there in the "Insert" menu - such maintains indentation and constrains space-wasted.
a!localVariables( local!searchProvince: null, local!searchLastName: null, local!searchPhoneNumber: null, local!customerIDs: null, { a!columnsLayout( columns: { a!columnLayout( contents: { a!textField( label: "Filter province", labelPosition: "ABOVE", placeholder: "-- Enter a province--", value: local!searchProvince, saveInto: local!searchProvince, refreshAfter: "UNFOCUS", validations: {} ) } ), a!columnLayout( contents: { a!textField( label: "Filter Last Name", labelPosition: "ABOVE", placeholder: "-- Enter a last name --", value: local!searchLastName, saveInto: local!searchLastName, refreshAfter: "UNFOCUS", validations: {} ) } ), a!columnLayout( contents: { a!textField( label: "Filter Phone Number", labelPosition: "ABOVE", placeholder: "-- Enter a phone number --", value: local!searchPhoneNumber, saveInto: local!searchPhoneNumber, refreshAfter: "UNFOCUS", validations: {} ) } ) } ), a!gridField( label: "Customer Details", labelPosition: "ABOVE", data: a!queryEntity( entity: cons!CD_CUSTOMERDETAILS_DSE, query: a!query( logicalExpression: a!queryLogicalExpression( operator: "AND", filters: { a!queryFilter( field: "province", operator: "includes", value: local!searchProvince ), a!queryFilter( field: "lastName", operator: "includes", value: local!searchLastName ), a!queryFilter( field: "phoneNumber", operator: "=", value: local!searchPhoneNumber ) }, ignoreFiltersWithEmptyValues: true ), pagingInfo: fv!pagingInfo ), fetchTotalCount: true ), columns: { a!gridColumn( label: "Customer ID", sortField: "customerID", value: fv!row.customerID, align: "END" ), a!gridColumn( label: "First Name", sortField: "firstName", value: fv!row.firstName ), a!gridColumn( label: "Last Name", sortField: "lastName", value: fv!row.lastName ), a!gridColumn( label: "Street Address", sortField: "streetAddress", value: fv!row.streetAddress ), a!gridColumn( label: "City", sortField: "city", value: fv!row.city ), a!gridColumn( label: "Province", sortField: "province", value: fv!row.province ), a!gridColumn( label: "Zip Code", sortField: "zipCode", value: fv!row.zipCode ), a!gridColumn( label: "Phone Number", sortField: "phoneNumber", value: fv!row.phoneNumber ), a!gridColumn( label: "Email", sortField: "email", value: fv!row.email ), a!gridColumn( label: "Heard About Us From", sortField: "heardAboutUsFrom", value: fv!row.heardAboutUsFrom ), a!gridColumn( label: "Feedback", sortField: "feedback", value: fv!row.feedback ), a!gridColumn( label: "Suggestions", sortField: "suggestions", value: fv!row.suggestions ), a!gridColumn( label: "Would Recommend Us", sortField: "wouldRecommendUs", value: fv!row.wouldRecommendUs ) }, initialSorts: a!sortInfo( field: "lastName", ascending: true ), selectable: true, selectionValue: local!customerIDs, selectionSaveInto: local!customerIDs, validations: {}, refreshOnVarChange: local!customerIDs ), a!buttonArrayLayout( buttons: { a!buttonWidget( label: "Delete", saveInto: a!startProcess( processModel: cons!CD_DELETE_CUSTOMER_DETAILS, processParameters: {customerIDs: local!customerIDs}, onSuccess: a!save(local!customerIDs, null) ), submit: true, style: "DESTRUCTIVE", validate: true ) }, align: "END" ) } )
OK. Your a!queryEntity does not know that it should refresh. I suggest to fetch the data in a global a!localVariables, add local!refreshCounter and a refreshOnVarChange on the local variables holding the data. Then increase that counter as Mike suggested.
That's better of course, though what I was really hoping was that you might edit the original comment to move the code into a code box..
That said - I'd have to guess that what you have here should work, provided your process is configured correctly. What change is happening in the process that you'd expect to see reflected in the grid upon completion? And can you post a screenshot of your completed process instance?