Depends on

20 views
Skip to first unread message

aurelien...@gmail.com

unread,
May 28, 2018, 10:32:32 PM5/28/18
to Keystone JS
Hello,
I was looking into dependsOn in the keystone model. It looks to be working fine when this is link to only one other field like this

MyModel.add({
  field1: {type: Types.select, options: 'en,zh,it'},
  field2: {type: String, dependsOn: {field1: 'en'})
})

or

MyModel.add({
  field1: {type: Types.select, options: 'en,zh,it'},
  field2: {type: String, dependsOn: {field1: ['en','it']})
})

these two examples work well.
However if I want the field one to be showing up regarding the result of two other fields like this

MyModel.add({
  field1: {type: Types.select, options: 'en,zh,it'},
  field2: {type: String, dependsOn: {field1: 'en', field2: 'UK'}),
  field3: {type: Types.select, options: 'UK,CHINA,ITALY'},
})

this won't work, wondering if this is a bug or normal expectation, the fact that dependsOn require an object would suggest it is a bug but I am not sure.
Also If someone spot me the good direction to fix this I'd like to propose a PR for this, I have seen some old PR to fix some other stuff but the code wasn't even using react at this time.
I would think this has to be fixed somewhere here https://github.com/keystonejs/keystone/tree/master/fields/types but I can't find where dependsOn is actually call there.
Many Thanks.

aurelien...@gmail.com

unread,
May 29, 2018, 5:23:28 AM5/29/18
to Keystone JS
Whatever I found how to fix it. Not sure this will be interested for anyone however
by:

var _ = require('lodash');

/**
 * Checks if something is an object
 *
 * @param  {Any} arg   The something we want to check the type of
 * @return {Boolean} If arg is an object or not
 */
function isObject (arg) {
return Object.prototype.toString.call(arg) === '[object Object]';
};

/**
 * Evaluates the visibility of a field based on its dependencies and their values
 *
 * @param  {Object|Any} dependsOn The dependsOn variable we get from the field
 * @param  {Object} values    The values currently in the fields
 * @return {Boolean}   If the current field should be displayed based
 *                            on it's dependencies and their values
 */
module.exports = function evalDependsOn (dependsOn, values) {
if (!isObject(dependsOn) || !Object.keys(dependsOn).length) {
return true;
}

// Checks if the current field should be displayed, based on the values of
// other fields and the dependsOn configuration of this field
var conditions = new Array();
_.each(dependsOn, function(v, k){
if (_.isArray(v)) {
conditions.push(_.includes(v, values[k]));
} else {
conditions.push(values[k] === v);
}
})
return _.every(conditions, function(item) { return item === true });

};

Of course that would require a double verification for a PR but works fine for me so far.
Reply all
Reply to author
Forward
0 new messages