cofi

cofi

  • Docs
  • Form Demos
  • Components Demos
  • Layout Demos
  • Editor
  • GitHub

›Form Class

Getting started

  • Introduction

Form Class

  • Installation
  • Overview
  • Arguments
  • Id
  • Data
  • Fields
  • Path
  • Component
  • Formatter & Parser
  • Dependencies
  • Required
  • Validators
  • Exclude Term
  • Disable Term
  • Require Term
  • Dependencies Change
  • Context
  • Dirty
  • Invalid
  • Errors
  • Processing
  • Pending Actions
  • Hooks
  • Term
  • Log
  • Error Codes
  • Actions
  • Definition Shorthand

Advanced Usages

  • Grid Usage
  • Form Persistency
  • Undo & Redo
  • Replay Actions
  • Track Actions
  • Server Validation
  • Entity Templates
  • Folder Structure

React Form

  • Installation
  • Overview
  • Form
  • Field
  • Components
  • Layout
  • Demos

Tools

  • Editor
  • DevTools

More Info

  • Test Cofi
  • Packages
  • Why Cofi?
  • Technologies
  • Videos
  • Channels

Contribute

  • Code of Conduct
  • Contributing Guide
  • Contributors

Dependencies Change

Define dependencies change for a field, in order to change its value / state when another field has changed its value.

Field Dependencies Change

Field dependencies change function is evaluated on init and when each of its dependencies fields value changed. To define field dependency change - a definition is required in the model.fields.someField object, and implementation is required in the resources.dependenciesChanges object.

Model

model.fields.someField.dependenciesChange - object. Contains:

NameTypeDescription
namerequired stringRepresents the key in resources.dependenciesChanges object
argsobjectCustom data to pass to the dependencies change function

Resources

resources.dependenciesChanges - dependenciesChanges. Required only if model.fields.someField.dependenciesChange defined. Key is the dependenciesChange name, and value is an object that contains:

NameTypeDescription
funcrequired functionEvaluates on each field’s dependencies value change. Function can be sync or async function (that resolves to the return value). More info
defaultArgsobjectDefault args for all fields. This will be shallow merged with field level dependency change args before passed to the func

func

function ({ 
  id, 
  value, 
  state, 
  dependencies { id: { value } },
  prevDependencies { id: { value } },
  args,
  context,
})

return value - object. Object defines which changes should be applied to the current field. Contains one or both of:

  1. value - the new value of that field
  2. state - the new state of that field

The function can also return undefined - in that case, the field value / state remains the same.

After the function completes, and the field is evaluated again (excludeTerm, validators and disableTerm), so even if the function doesn't change anything (returned undefined), the field is still evaluated again.

Example

Each time 'country' changes - 'city' value is initiated to the country's capital city, and state's items are replaces to the country's cities.

/* 
countryToCities - object like { 
  ISRAEL: [{ label: 'Jerusalem', value: 'JERUSALEM', capital: true }, { label: 'Tel Aviv', value: 'TEL_AVIV', }],
  MEXICO: [{ label: 'Mexico City', value: 'MEXICO_CITY', capital: true }, { label: 'Cancun', value: 'CANCUN', }],
}
*/
import { countryToCities } from './consts'; 

const model = {
  // ...
  fields: {
    country: {
      // ...
    }.
    city: {
      // ...
      dependencies: ['country']
      dependenciesChange: { name: 'cityDependenciesChange' }, 
    }
  },
  data: { country: 'ISRAEL', city: 'TEL_AVIV' },
};

const resources = {
  dependenciesChanges: {
    cityDependenciesChange: {
      func: (props) => {
        if (props.prevDependencies && 
          (props.dependencies.country.value !== props.prevDependencies.country.value)) {
          const cities = countryToCities[props.dependencies.country.value];
          
          return {
            value: cities.find(city => city.capital).value,
            state: { ...props.state, items: cities },
          };
        }

        return undefined; // no changes needed
      }
    }
  }
};

Shorthand

Definition shorthand for dependencies changes can be found in definition shorthand documentation.

Circular Dependencies

  1. Circular dependencies can happen only if these 4 conditions apply simultaneously:
  • Field “b” defines a dependency for field “a” (field.dependencies = [‘a’])
  • Field “a” defines a dependency for field “b” (field.dependencies = [‘b’])
  • Field “b” defines a “field.dependenciesChange” func that returns “value” change in every case
  • Field “a” defines a “field.dependenciesChange” func that returns “value” change in every case

Example

const model = {
  // ...
  fields: {
    a: {
      // ...
      dependencies: ['b'],
      dependenciesChange”: 'aDependenciesChange',
    }, 
    b: {
      // ...
      dependencies: ['a'],
      dependenciesChange”: 'bDependenciesChange',
    }
  },
};

const resources = {
  dependenciesChanges: {
    aDependenciesChange: {
        func: (props) => ({ value: props.dependencies.b.value + 1 }),
    },
    bDependenciesChange: {
      func: (props) => ({ value: props.dependencies.a.value + 1 }),
    },
  }
}
  1. Circular dependencies can happen also on a larger chain(a -> b -> c -> d -> a)

  2. There are also non circular cases like:

  • “a” changes
    • triggers “b” to change value (in dependencyChange func return value to change)
      • triggers “a” to change value (in dependencyChange func return value to change)
        • triggers “b” to evaluate (in dependencyChange func return undefined)

Example

a = 0, b = 0. a changes to 1 -> triggers b change to 1 -> triggers a change to 2 -> trigger b to return undefined and not change anything. loop ends.

const model = {
  // ...
  fields: {
    a: {
      // ...
      dependencies: ['b'],
      dependenciesChange”: 'aDependenciesChange',
    }, 
    b: {
      // ...
      dependencies: ['a'],
      dependenciesChange”: 'bDependenciesChange',
    }
  },
};

const resources = {
  dependenciesChanges: {
    aDependenciesChange: {
      func: (props) => (props.dependencies.b.value < 2 ? { value: props.value + 1 } : undefined);
    },
    bDependenciesChange: {
      func: (props) => (props.dependencies.a.value < 2 ? ),
    },
  }
};
← Require TermContext →
  • Field Dependencies Change
    • Model
    • Resources
    • Example
    • Shorthand
    • Circular Dependencies
cofi
Copyright © 2021 Verizon Media
DOCS
IntroductionForm ClassReact FormReact ComponentsReact Layout
DEMOS
React FormReact ComponentsReact Layout
CONTRIBUTING
Code Of ConductContributing GuideContributorsUsers
CHANNELS
StarGitHubStack OverflowMediumVideos