Forum Discussion

Jacky_C's avatar
Jacky_C
New Contributor III
3 months ago

Disable a button on a dashboard when the form status is 'Completed'

Hi all,

I am trying to build a business rule to dynamically disable a button (become invisible) once the form status is completed. May I know is there any function I could leverage on to fulfill this functionality?

Any suggestion would be appreciated. Thank you.

Best,

Jacky

  • Hi Jacky,

    We can tweak the function to check for each form.

    To do this you need to create a dictionary that stores the form name and the form status. Declare this as a private member of the class, where you declare global variables and then create a method in the class that will populate this variable with data. Please refer to the code below.

    Private formStatusDict As New Dictionary(Of String, XFFormStatus)
    
    ' Function to create the dictionary of form names and statuses
    		Private Sub PopulateFormStatusDictionary()
    		    ' Retrieve the workflow name, scenario, and time key
    		    Dim wfName As String = args.NameValuePairs("WFName") ' Hard-code if only checking one form
    		    Dim wfScenario As String = ScenarioDimHelper.GetNameFromID(si, si.WorkflowClusterPk.ScenarioKey)
    		    Dim wfTime As String = TimeDimHelper.GetNameFromId(si.WorkflowClusterPk.TimeKey)
    		    Dim wfClusterPk As WorkflowUnitClusterPk = BRApi.Workflow.General.GetWorkflowUnitClusterPk(si, wfName, wfScenario, wfTime)
    		    
    		    ' Get the required forms and populate the dictionary
    		    Dim formsList As List(Of XFFormSummaryInfo) = BRApi.Forms.Metadata.GetForms(si, wfClusterPk).RequiredForms
    		    formStatusDict.Clear() ' Clear the dictionary to avoid duplicates
    		    
    		    For Each form In formsList
    		        ' Add each form name as key and its status as value
    		        formStatusDict(form.Name) = form.Status
    		    Next
    		End Sub

    From your form status parameter, you need to add form name and enter the name of the form in square brackets (you will need a parameter for each form in the workflow), your parameter literal value will look like this

    XFBR(Your_XFBR_Rule,GetFormStatus,WFName=|WFProfile|, FormName=[Test Form Name])

    Now this will run the GetFormStatus function after populating the forms dictionary, the code will change as below:

    If args.FunctionName.XFEqualsIgnoreCase("GetFormStatus")
    					Dim formName As String = args.NameValuePairs.XFGetValue("FormName")
    					Me.PopulateFormStatusDictionary()
    					Return Me.GetFormStatus(formName)
    				End If
    
    ' Function to check if a specific form is completed
    		Private Function GetFormStatus(formName As String) As String
    		    ' Ensure the dictionary has been populated
    		    If Not formStatusDict.ContainsKey(formName) Then
    		        Throw New System.Exception($"Form '{formName}' not found or dictionary not populated.")
    		    End If
    			
    			Dim status As XFFormStatus = Me.formStatusDict(formName)
    
    		    If status.Completed Then
    				Return "Completed"
    			Else
    				Return "Not Completed"
    			End If
    		    
    		End Function

    At the top add the below global variables and initialize them in the main function

    When you run this you should be able to get the same outcome but now at a form level.

     

  • EdwinS's avatar
    EdwinS
    New Contributor II

    Hi, 

    In the button you can use the XFBR rule to indicate whether to show or hide the button.
    1. In button properties --> Formatting --> Display Format
    Assign IsVisible property to the XFBR rule

    IsVisible = XFBR(Your_XFBR_Rule, YourFunctionName, FormCompleted=|!ParameterStoringFormStatus!|

    2. In the XFBR rule, you can have a method that checks the form status and return whether the button should be shown or hidden, refer to the code snippet below.

    'In the main function add the condition passed in the button
    If args.FunctionName.XFEqualsIgnoreCase("YourFunctionName") Then
         Return Me.YourFunctionName(si, globals, api, args)
    End If
    
    'Create a method that will get the form status and return the result
    'The method is YourFunctionName
            Public Function YourFunctionName(ByVal si As SessionInfo, ByVal globals As BRGlobals, ByVal api As Object, ByVal args As DashboardStringFunctionArgs) As String
                Try
                    'Get form status to test
                    Dim formComplete As String = args.NameValuePairs.XFGetValue("FormCompleted")
    
                    'Check to see if the form is completed (Can be used to hide objects if the form is completed)
                    If formComplete.XFEqualsIgnoreCase("Completed") Then
                        'Form is completed, Return False
                        Return "False"
                    Else
                        'Form is not completed, Return True
                        Return "True"
                    End If
    
                Catch ex As Exception
                    Throw ErrorHandler.LogWrite(si, New XFException(si, ex))
                End Try
            End Function

     

    • Jacky_C's avatar
      Jacky_C
      New Contributor III

      Hi Edwin, 

      Thank you so much for providing the relevant function and sample code. I am able to create the relevant XFBR rule, but I am not sure how can I store the Form status in a parameter? Is there a standard function in OneStream that can retrieve the current form status?

      Again, thank you for your suggestion on the IsVisible function and XFBR rule, it is really useful.

       

      Best,

      Jacky

       

      • EdwinS's avatar
        EdwinS
        New Contributor II

        Hi Jacky, is the form in the workflow?

        If it is in the workflow step, then you can retrieve the status using the below XFBR rule, and then attach it to the literal value parameter.

        Your parameter literal value = XFBR(Your_XFBR_Rule, GetFormStatus, WFName=|WFProfile|)

        'In the main function add a condition to call GetFormStatus function
        If args.FunctionName.XFEqualsIgnoreCase("GetFormStatus") Then
             Return Me.GetFormStatus(si, globals, api, args)
        End If
        
        'Create a method that will get the form status
                Private Function GetFormStatus(ByVal si As SessionInfo, ByVal globals As BRGlobals, ByVal api As Object, ByVal args As DashboardStringFunctionArgs) As String
        			'Code will go here
        			Dim wfName As String = args.NameValuePairs("WFName")' You can hard code this value if you want to check one form only
        			Dim wfScenario As String = ScenarioDimHelper.GetNameFromID(si, si.WorkflowClusterPk.ScenarioKey)
        			Dim wfTime As String = TimeDimHelper.GetNameFromId(si.WorkflowClusterPk.TimeKey)
        			Dim wfClusterPk As WorkflowUnitClusterPk = BRApi.Workflow.General.GetWorkflowUnitClusterPk(si, wfName, wfScenario, wfTime)
        			Dim wfStatus As WorkflowInfo = BRApi.Workflow.Status.GetWorkflowStatus(si, wfClusterPk)
        			
        			If wfStatus.CurrentStep.Status.Equals(WorkflowStatusTypes.Completed) = "True" Then
        				Return "Completed"
        			Else
        				Return "Not Completed"
        			End If
        			
        		End Function

        I attached the parameter to the label to test this functionality on the form that is completed in the workflow, and I got the results below.