RXNT/react-jsonschema-form-conditionals

The Engine should run again if the formData changes as the result of a rule

Steffan-Ennis opened this issue · 1 comments

I have a rule that populates a set of fields, which should fire another rule

handleChange in applyRules.js

handleChange = state => {
      let { formData } = state;
      runRules(formData, this.props).then(conf => {
        this.updateState(formData, conf);
        if (this.props.onChange) {
          state = Object.assign({}, state, conf);
          this.props.onChange(state);
        }
      });
    };

could be something like this

handleChange = state => {
  let { formData } = state;
  runRules(formData, this.props).then(conf => {
    this.updateState(formData, conf);
    if (this.props.onChange) {
      if(!deepEqual(formData, conf.formData  )) {
        this.handleChange({ formData: conf.formData })
      } else {
        state = Object.assign({}, state, conf);
        this.props.onChange(state);
      }
    }
  });
};

Sample rules

[
  {
    "title": "Rule #2",
    "description": "This hides Address, Email, Gender and the Password fields until First Name and Last Name have a value",
    "conditions": {
      "and": [
        {
          "or": [
            {
              "registration.firstName": "empty"
            },
            {
              "registration.lastName": "empty"
            }
          ]
        }
      ]
    },
    "event": {
      "type": "remove",
      "params": {
        "field": [
          "address",
          "registration.gender",
          "registration.email",
          "registration.password",
          "registration.confirmPassword"
        ]
      }
    }
  },
  {
    "title": "Rule #3",
    "description": "prefills firstName",
    "conditions": {
      "and": [
        {
          "registration.firstName": {
            "_equals": "Barry"
          }
        }
      ]
    },
    "event": {
      "params": {
        "field": [
          "registration.lastName"
        ],
        "options": {
          "registration.lastName": "White",
          "registration.gender": "Male"
        }
      },
      "type": "populate"
    }
  }
]

At the moment a second Higher Order Component needs to be written with the following to achieve this,


    componentWillReceiveProps (nextProps) {
      if(!deepEqual(nextProps.formData,this.props.formData)){
        // Rules do not run again when formData changes as a result from a rule
        this.onChange({formData: nextProps.formData})
      }

@Steffan-Ennis In order to handle this you just need to change the order of the rules (I've added a test in the commit)

Also, we are going to have #36 shipped by the end of the month to address this.