Conditions - smbc-digital/form-builder GitHub Wiki

Conditions

Overview

A condition is like equal to or greater than in normal programming languages. It compares a value of a form element to a value and returns true if a condition is met. If the condition or conditions defined in the behavior are true, The action defined in the behavior is carried out.

Conditions can also be used within elements to dictate whether a component should be optional. Inside an element's properties, you can create an OptionalIf object that contains: questionId, conditionType and comparisonValue.

The conditions are enumerated as follows


namespace form_builder.Enum
{
    public enum ECondition
    {
        Undefined = 0,
        EqualTo,
        PaymentAmountEqualTo,
        Contains,
        IsNullOrEmpty,
        IsFileUploadNullOrEmpty,
        IsBefore,
        IsAfter,
        GreaterThan,
        LessThan,
        GreaterThanEqualTo,
        LessThanEqualTo,
        EndsWith,
        IsOneOf,
        Any
    }
}

Any Condition

Another condition type is Any, this can be used when you require any x number of conditions to be true, currently conditions are either valid or not. With Any you can supply x number of conditions and specify how many of those needs to be true for the condition as a whole to be true. This can be useful for pages which are displayed if a user has selected a number of possible options. This condition can be used in conjunction with any other conditions which are required to be true.

The number of conditions required to be true are specified within comparisonValue, and the conditions are specified within Conditions array.

  "conditionType": "Any",
  "comparisonValue": "1",
  "Conditions": []

Example of Any condition

"Behaviours": [
    {
        "conditions": [
            {
                "conditionType": "Any",
                "comparisonValue": "1",
                "Conditions": [
                    {
                        "questionId": "whatDoYouWantToReport",
                        "conditionType": "Contains",
                        "comparisonValue": "highWaterLevels"
                    },
                    {
                        "questionId": "whatDoYouWantToReport",
                        "conditionType": "Contains",
                        "comparisonValue": "flood"
                    }
                ]
            }
        ],
        "behaviourType": "GoToPage",
        "pageSlug": "what-do-you-want-to-report"
    }
]
}

Creating a new condition

In this example we will create an example that compares a monetary value.If the monetary value is greater than the value it returns true. This comparator will be called CostsMoreThan.

1.Enum

Go to the Econdition.csin the Enum folder and add CostsMoreThan in the enum as follows:

public enum ECondition
    {
        Undefined = 0,
        EqualTo,
        CheckboxContains,
        IsNullOrEmpty,
        IsBefore,
        IsAfter,
        GreaterThan,
        LessThan,
        GreaterThanEqualTo,
        LessThanEqualTo,
        EndsWith,
        CostsMoreThan /*New Value*/
    }

2. Creating the comparator

A comparator(my neologism)

In the conditions folder create a new class CurrencyComparotor and add the following

using System;
using System.Collections.Generic;
using form_builder.Models;

namespace form_builder.Conditions
{
    public static class CurrencyComparator
    {

        public static bool CostsMoreThan (Condition condition, Dictionary<string, dynamic> viewModel)
        {
            if (viewModel.ContainsKey(condition.QuestionId) &&
                 decimal.Parse(viewModel[condition.QuestionId]) > GetDecimalValue(condition.ComparisonValue))
                return true;
            return false;
        }


        public static decimal GetDecimalValue(string comparisonValue)
        {
            var success = decimal.TryParse(comparisonValue, out decimal decValue);
            if (success)
                return decValue;
            return 0.00M;
        }
    }
}

  1. Adding it to ConditionValidator

In ConditionValidatorClass there is a dictionary object that maps ECondition to Comparator functions

So add the new Enumerator value and the new CurrencyComparotFunction, CostMoreThan, to the the ConditionList dictionaryas shown below:

using System;
using System.Collections.Generic;
using form_builder.Enum;
using form_builder.Models;

namespace form_builder.Conditions
{
    public class ConditionValidator
    {
        private Dictionary<ECondition, Func<Condition, Dictionary<string, dynamic>, bool>> ConditionList =

        new Dictionary<ECondition, Func<Condition, Dictionary<string, dynamic>, bool>>()
        {
            { ECondition.IsBefore, DateComparator.DateIsBefore },
            { ECondition.IsAfter, DateComparator.DateIsAfter },
            { ECondition.IsNullOrEmpty, StringComparator.IsNullOrEmpty },
            { ECondition.EqualTo, StringComparator.IsEqualTo },
            { ECondition.CheckboxContains, StringComparator.CheckboxContains },
            { ECondition.GreaterThan, IntegerComparator.IsGreaterThan },
            { ECondition.LessThan, IntegerComparator.IsLessThan },
            { ECondition.GreaterThanEqualTo, IntegerComparator.IsGreaterThanEqualTo },
            { ECondition.LessThanEqualTo, IntegerComparator.IsLessThanEqualTo },
            { ECondition.EndsWith, StringComparator.EndsWith },

            //New Dictionary Item
            { ECondition.CostsMoreThan, CurrencyComparator.CostsMoreThan}
        };

        public bool IsValid(Condition condition, Dictionary<string, dynamic> viewModel)
        {
            return ConditionList[condition.ConditionType](condition, viewModel);
        }

    }
}

4. Adding it to a form

If you want to add a condition where if something goes a specific page depending on whether something costs more than £50 pounds. Create the following behaviour

{
    "behaviourType": "GoToPage",
    "page-slug": "more-than-fifty"
     "conditions":[
      {
            "conditionType": "CostsMoreThan",
            "comparisonValue": 50.00,
            "questionId": "cost"
      }
   ]
}