fieldName: '@name',
defn: '='
},
- controller: function($scope, $element, crmApi4, $timeout) {
+ 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);
}
- // Set default value
- if (ctrl.defn.afform_default) {
- // Wait for parent controllers to initialize
- $timeout(function() {
- $scope.dataProvider.getFieldData()[ctrl.fieldName] = ctrl.defn.afform_default;
- });
+ // Wait for parent controllers to initialize
+ $timeout(function() {
+ // Unique field name = entity_name index . join . field_name
+ var entityName = ctrl.afFieldset.getName(),
+ joinEntity = ctrl.afJoin ? ctrl.afJoin.entity : null,
+ uniquePrefix = '',
+ urlArgs = $location.search();
+ if (entityName) {
+ var index = ctrl.getEntityIndex();
+ uniquePrefix = entityName + (index ? index + 1 : '') + (joinEntity ? '.' + joinEntity : '') + '.';
+ }
+ // Set default value from url with uniquePrefix + fieldName
+ if (urlArgs && 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) {
+ 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() {
// 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() {