16 Oct 2020
Technology
3
min read
Aleksandar Kisimov
,
Front-end Developer
This functionality comes out of the box with Sitecore. It isn’t, however, an out of the box feature of the React JSS application. Instead, it requires manual setup.
Configuration
The base Sitecore Forms in JSS setup has been covered in Sitecore forms & JSS: Field factory. This article focuses on applying rendering logic to the pre-existing fields.
Existing Sitecore documentation covers this topic in greater detail, but in summary:
Go to Sitecore Forms editor
Edit a form (or create a new one)
Select a field in the form and find the Edit conditions option in the edit panel
Setting up the conditional logic in the client app
The way this is handled in a React JSS app is with the help of Redux. This is due to the form’s inability to pass down states to its child components. If this changes in the future it would eliminate the need for using Redux. Alternatively, React’s own context API can be used to achieve similar results.
Field conditions
To ensure the form contains all the fields’ data in its ‘props’ object used to create the global state, check each form field for a condition. Each field contains potential conditions in its model in fieldConditions, which looks like the following example:
The GUIDs in the example are Sitecore items which will not change. These can be used later for referencing against certain keywords.
When setting a condition to a form field, it gets assigned an action, condition and a matchingType as part of default functionality:
The action contains information about the targeted item where:
actionTypeId is one of two GUIDs to represent hide or show
fieldId is the ID of the item targeted by the condition which can be later used when executing the logic
The condition contains information about the condition set in Sitecore where:
fieldId is the ID of the field whose value needs to be tracked in order to execute the logic
operatorId is one of several constant items which hold the logic operator, i.e. what to do with the condition fieldId value. For example the above GUID, {1D38B217-A2EE-4E7B-B6ED-13E751462FEB} means is equal to
value is the value to be used by the operator
Building the global state
The conditional rendering functionality is using Redux to hold the form's condition data. The global state is an object containing three key-value pairs:
conditionFields: An array of unique fieldId values - fields that are part of a condition or an action
conditions: An object containing all conditions set against the appropriate field where each key is the targeted item fieldId and the value is an array of all conditions
fieldValues: An object containing each form field’s value where the key is that field’s fieldId - these fieldValues get updated later using global state logic which helps execute the conditions
Before a global state is created, however, all the conditional rendering data needs to be collected in one place. For that, the form fields are iterated over and checked for a condition in fieldConditions.
For each field the iterator checks whether it's part of an action or a condition. It checks if the fieldId has already been stored in the global state and if not, pushes it.
After the data has been collated, it gets dispatched to set the global state. If there are no conditions set in Sitecore, the global form state doesn't get updated.
The conditional rendering logic
Now that the data has been gathered, the conditional rendering logic needs to be mapped out.
Constants
There are a number of items in Sitecore used to set actions, operators, and matchTypes. These are settings items. They are considered constants once they're created as they are unique and their GUIDs won’t change. For readability and an easier reference, those are exported in a separate constants file:
checkConditions logic
The conditional rendering logic is handled in ConditionalRendering/index.js. The main export of this file is the checkConditions helper function that each form field will call later on. It needs two parameters to be passed to it:
The fieldValues stored in the global state
The conditions it needs to be verifying against. It iterates over each condition grouping and returns a Boolean indicating whether the form field should show/hide
The checkConditions helper starts by calling matchingTypes which checks whether the matchingType of the field is any or all conditions. Then it attempts to validate the conditions accordingly.
The matchingTypes function accepts the fieldValues state and conditions item as parameters. Depending on the conditions matching type, it attempts to validate each condition by passing the operator, relevant field value, and the value to be compared against (defined in the condition in Sitecore) as valueAgainst. Following the validation, and the shouldHide being set correctly, handleActionType is then called to determine the final action (show/hide) based on the shouldHide result.
The validate helper uses a GUID to perform comparisons between the current value of the condition field, and the expected value set in Sitecore (valueAgainst).
Finally, the handleActionType determines whether a field should be shown/hidden based on the actionType set in Sitecore.
Using the global state information to conditionally render fields
The newly created checkConditions helper can now be utilised in individual fields. Each form field checks whether it’s part of a condition. If it is, it checks whether it should hide, and then starts updating its value in the global state.
NOTE: When building a form, any fields inside a section will not be iterated unless explicitly done so in the initial global state setup. This is due to the fact that the fields within a section are mapped to their respective props rather than the overall Form props. This applies to a section within a section and so on.
Working with Codehouse
Our development team are constantly looking at ways to improve the development process and user experience. We work on exciting design and build projects often on CMS like Sitecore. Get in touch to find out more.