controller: function($scope, $element, crmApi4, $timeout, $location) {
var ts = $scope.ts = CRM.ts('org.civicrm.afform'),
ctrl = this,
+ // Prefix used for SearchKit explicit joins
+ namePrefix = '',
boolOptions = [{id: true, label: ts('Yes')}, {id: false, label: ts('No')}],
+ // Used to store chain select options loaded on-the-fly
+ chainSelectOptions = null,
// Only used for is_primary radio button
noOptions = [{id: true, label: ''}];
$element.addClass('af-field-type-' + _.kebabCase(ctrl.defn.input_type));
+ if (this.defn.name !== this.fieldName) {
+ namePrefix = this.fieldName.substr(0, this.fieldName.length - this.defn.name.length);
+ }
if (ctrl.defn.search_range) {
// Initialize value as object unless using relative date select
// ChainSelect - watch control field & reload options as needed
if (ctrl.defn.input_type === 'ChainSelect') {
- $scope.$watch('dataProvider.getFieldData()[defn.input_attrs.control_field]', function(val) {
- if (val) {
+ var controlField = namePrefix + ctrl.defn.input_attrs.control_field;
+ $scope.$watch('dataProvider.getFieldData()["' + controlField + '"]', function(val) {
+ // After switching option list, remove invalid options
+ function validateValue() {
+ var options = $scope.getOptions(),
+ value = $scope.dataProvider.getFieldData()[ctrl.fieldName];
+ if (_.isArray(value)) {
+ _.remove(value, function(item) {
+ return !_.find(options, function(option) {return option.id == item;});
+ });
+ } else if (value && !_.find(options, function(option) {return option.id == value;})) {
+ $scope.dataProvider.getFieldData()[ctrl.fieldName] = '';
+ }
+ }
+ if (val && (typeof val === 'number' || val.length)) {
+ $('input[crm-ui-select]', $element).addClass('loading').prop('disabled', true);
var params = {
- where: [['name', '=', ctrl.fieldName]],
- select: ['options'],
- loadOptions: ['id', 'label'],
- values: {}
+ name: ctrl.afFieldset.getFormName(),
+ modelName: ctrl.afFieldset.getName(),
+ fieldName: ctrl.fieldName,
+ joinEntity: ctrl.afJoin ? ctrl.afJoin.entity : null,
+ values: $scope.dataProvider.getFieldData()
};
- params.values[ctrl.defn.input_attrs.control_field] = val;
- crmApi4($scope.dataProvider.getEntityType(), 'getFields', params, 0)
+ crmApi4('Afform', 'getOptions', params)
.then(function(data) {
- ctrl.defn.options = data.options;
+ $('input[crm-ui-select]', $element).removeClass('loading').prop('disabled', !data.length);
+ chainSelectOptions = data;
+ validateValue();
});
+ } else {
+ chainSelectOptions = null;
+ validateValue();
}
- });
+ }, true);
}
// Wait for parent controllers to initialize
var index = ctrl.getEntityIndex();
uniquePrefix = entityName + (index ? index + 1 : '') + (joinEntity ? '.' + joinEntity : '') + '.';
}
- // Set default value based on url
+ // Set default value from url with uniquePrefix + fieldName
if (urlArgs && urlArgs[uniquePrefix + ctrl.fieldName]) {
- $scope.dataProvider.getFieldData()[ctrl.fieldName] = urlArgs[uniquePrefix + ctrl.fieldName];
+ setValue(urlArgs[uniquePrefix + ctrl.fieldName]);
+ }
+ // Set default value from url with fieldName only
+ else if (urlArgs && urlArgs[ctrl.fieldName]) {
+ $scope.dataProvider.getFieldData()[ctrl.fieldName] = urlArgs[ctrl.fieldName];
}
// Set default value based on field defn
else if (ctrl.defn.afform_default) {
- $scope.dataProvider.getFieldData()[ctrl.fieldName] = ctrl.defn.afform_default;
+ setValue(ctrl.defn.afform_default);
}
});
-
};
+ // Set default value; ensure data type matches input type
+ function setValue(value) {
+ if (ctrl.defn.input_type === 'Number' && ctrl.defn.search_range) {
+ if (!_.isPlainObject(value)) {
+ value = {
+ '>=': +(('' + value).split('-')[0] || 0),
+ '<=': +(('' + value).split('-')[1] || 0),
+ };
+ }
+ } else if (ctrl.defn.input_type === 'Number') {
+ value = +value;
+ } else if (ctrl.defn.search_range && !_.isPlainObject(value)) {
+ value = {
+ '>=': ('' + value).split('-')[0],
+ '<=': ('' + value).split('-')[1] || '',
+ };
+ }
+
+ $scope.dataProvider.getFieldData()[ctrl.fieldName] = value;
+ }
+
// Get the repeat index of the entity fieldset (not the join)
ctrl.getEntityIndex = function() {
// If already in a join repeat, look up the outer repeat
// Params for the Afform.submitFile API when uploading a file field
ctrl.getFileUploadParams = function() {
return {
- entityName: ctrl.afFieldset.modelName,
+ modelName: ctrl.afFieldset.getName(),
fieldName: ctrl.fieldName,
joinEntity: ctrl.afJoin ? ctrl.afJoin.entity : null,
entityIndex: ctrl.getEntityIndex(),
};
$scope.getOptions = function () {
- return ctrl.defn.options || (ctrl.fieldName === 'is_primary' && ctrl.defn.input_type === 'Radio' ? noOptions : boolOptions);
+ return chainSelectOptions || ctrl.defn.options || (ctrl.fieldName === 'is_primary' && ctrl.defn.input_type === 'Radio' ? noOptions : boolOptions);
};
$scope.select2Options = function() {