diff --git a/ext/afform/admin/ang/afGuiEditor/afGuiCondition.component.js b/ext/afform/admin/ang/afGuiEditor/afGuiCondition.component.js index 59d320773c6b..a2f079612daf 100644 --- a/ext/afform/admin/ang/afGuiEditor/afGuiCondition.component.js +++ b/ext/afform/admin/ang/afGuiEditor/afGuiCondition.component.js @@ -11,37 +11,33 @@ }, templateUrl: '~/afGuiEditor/afGuiCondition.html', controller: function ($scope) { - var ts = $scope.ts = CRM.ts('org.civicrm.afform_admin'), + let ts = $scope.ts = CRM.ts('org.civicrm.afform_admin'), ctrl = this; let conditionValue; - this.operators = [ - { - "key": "==", - "value": "=", - }, - { - "key": "!=", - "value": "≠", - }, - { - "key": ">", - "value": ">", - }, - { - "key": "<", - "value": "<", - }, - { - "key": ">=", - "value": "≥", - }, - { - "key": "<=", - "value": "≤", - } - ]; + let operatorCache = {}; + + const allOperators= { + '=': '=', + '!=': '≠', + '>': '>', + '<': '<', + '>=': '≥', + '<=': '≤', + 'CONTAINS': ts('Contains'), + 'NOT CONTAINS': ts("Doesn't Contain"), + 'IN': ts('Is One Of'), + 'NOT IN': ts('Not One Of'), + 'LIKE': ts('Is Like'), + 'NOT LIKE': ts('Not Like'), + 'IS EMPTY': ts('Is Empty'), + 'IS NOT EMPTY': ts('Not Empty'), + }; this.$onInit = function() { + // Update legacy operator '==' to the new preferred '=' + if (getOperator() === '==') { + setOperator('='); + } $scope.$watch('$ctrl.field', updateOperators); }; @@ -52,7 +48,7 @@ function setOperator(op) { if (op !== getOperator()) { ctrl.clause[ctrl.offset] = op; - ctrl.changeClauseOperator(); + updateOperators(); } } @@ -70,14 +66,6 @@ ctrl.clause[1 + ctrl.offset] = JSON.stringify(val); } - // Getter/setter for use with ng-model - this.getSetOperator = function(op) { - if (arguments.length) { - setOperator(op); - } - return getOperator(); - }; - // Getter/setter for use with ng-model this.getSetValue = function(val) { if (arguments.length) { @@ -88,17 +76,64 @@ // Return a list of operators allowed for the current field this.getOperators = function() { - return ctrl.operators; + var field = ctrl.field || {}, + allowedOps = field.operators; + if (!allowedOps && field.data_type === 'Boolean') { + allowedOps = ['=', '!=', 'IS EMPTY', 'IS NOT EMPTY']; + } + if (!allowedOps && _.includes(['Boolean', 'Float', 'Date'], field.data_type)) { + allowedOps = ['=', '!=', '<', '>', '<=', '>=', 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN', 'IS EMPTY', 'IS NOT EMPTY']; + } + if (!allowedOps && (field.data_type === 'Array' || field.serialize)) { + allowedOps = ['CONTAINS', 'NOT CONTAINS', 'IS EMPTY', 'IS NOT EMPTY']; + } + if (!allowedOps) { + return allOperators; + } + var opKey = allowedOps.join(); + if (!operatorCache[opKey]) { + operatorCache[opKey] = filterObjectByKeys(allOperators, allowedOps); + } + return operatorCache[opKey]; }; + function filterObjectByKeys(obj, whitelist) { + return Object.keys(obj) + .filter(key => whitelist.includes(key)) + .reduce((filteredObj, key) => { + filteredObj[key] = obj[key]; + return filteredObj; + }, {}); + } + // Ensures clause is using an operator that is allowed for the field function updateOperators() { - if ((!getOperator() || !_.includes(_.pluck(ctrl.getOperators(), 'key'), getOperator()))) { - setOperator(ctrl.getOperators()[0].key); + if (!getOperator() || !(getOperator() in ctrl.getOperators())) { + setOperator(Object.keys(ctrl.getOperators())[0]); } } + // Returns false for 'IS NULL', 'IS EMPTY', etc. true otherwise. + this.operatorTakesInput = function() { + return getOperator().indexOf('IS ') !== 0; + }; + this.changeClauseOperator = function() { + // Add/remove value depending on whether operator allows for one + if (!ctrl.operatorTakesInput()) { + ctrl.clause.length = ctrl.offset + 1; + } else { + if (ctrl.clause.length === ctrl.offset + 1) { + ctrl.clause.push(''); + } + // Change multi/single value to/from an array + var shouldBeArray = _.includes(['IN', 'NOT IN'], getOperator()); + if (!_.isArray(getValue()) && shouldBeArray) { + setValue([]); + } else if (_.isArray(getValue()) && !shouldBeArray) { + setValue(''); + } + } }; } diff --git a/ext/afform/admin/ang/afGuiEditor/afGuiCondition.html b/ext/afform/admin/ang/afGuiEditor/afGuiCondition.html index 8ce63c5aca2a..fe58f933f1c0 100644 --- a/ext/afform/admin/ang/afGuiEditor/afGuiCondition.html +++ b/ext/afform/admin/ang/afGuiEditor/afGuiCondition.html @@ -1,2 +1,6 @@ - - + +