{{:: ts('Required') }}
</a>
</li>
-<li ng-if="$ctrl.fieldDefn.input_type === 'Existing'">
- <a href ng-click="toggleSkipPermissions(); $event.stopPropagation(); $event.target.blur();" title="{{:: ts('Allows non-permissioned users to access any record returned by the saved search') }}">
- <i class="crm-i fa-{{ getProp('skip_permissions') ? 'check-' : '' }}square-o"></i>
- {{:: ts('Disable Permission Checks') }}
- </a>
-</li>
<li ng-if="$ctrl.fieldDefn.input_type !== 'Existing'">
<a href ng-click="toggleDefaultValue(); $event.stopPropagation(); $event.target.blur();" title="{{:: ts('Pre-fill this field with a value') }}">
<i class="crm-i fa-{{ $ctrl.hasDefaultValue ? 'check-' : '' }}square-o"></i>
getSet('required', !getSet('required'));
};
- $scope.toggleSkipPermissions = function() {
- getSet('skip_permissions', !getSet('skip_permissions'));
- };
-
$scope.toggleHelp = function(position) {
getSet('help_' + position, $scope.propIsset('help_' + position) ? null : (ctrl.getDefn()['help_' + position] || ts('Enter text')));
};
}
}
// Id field for selecting existing entity
- if ($field['name'] === CoreUtil::getIdFieldName($entityName)) {
+ if ($action === 'update' && $field['name'] === CoreUtil::getIdFieldName($entityName)) {
$entityTitle = CoreUtil::getInfoItem($entityName, 'title');
$field['input_type'] = 'Existing';
$field['entity'] = $entityName;
protected function loadEntities() {
foreach ($this->_formDataModel->getEntities() as $entityName => $entity) {
$this->_entityIds[$entityName] = [];
+ $idField = CoreUtil::getIdFieldName($entity['type']);
if (!empty($entity['actions']['update'])) {
- if (!empty($this->args[$entityName]) && !empty($entity['url-autofill'])) {
- $ids = array_map('trim', explode(',', $this->args[$entityName]));
+ if (
+ !empty($this->args[$entityName]) &&
+ (!empty($entity['url-autofill']) || isset($entity['fields'][$idField]))
+ ) {
+ $ids = (array) $this->args[$entityName];
// Limit number of records to 1 unless using af-repeat
$ids = array_slice($ids, 0, !empty($entity['af-repeat']) ? $entity['max'] ?? NULL : 1);
$this->loadEntity($entity, $ids);
*/
private function loadEntity(array $entity, array $ids) {
$api4 = $this->_formDataModel->getSecureApi4($entity['name']);
+ $idField = CoreUtil::getIdFieldName($entity['type']);
+ if (!empty($entity['fields'][$idField]['saved_search'])) {
+ $ids = $this->validateBySavedSearch($entity, $idField, $ids);
+ }
+ if (!$ids) {
+ return;
+ }
$result = $api4($entity['type'], 'get', [
'where' => [['id', 'IN', $ids]],
'select' => array_keys($entity['fields']),
- ])->indexBy('id');
+ ])->indexBy($idField);
foreach ($ids as $index => $id) {
$this->_entityIds[$entity['name']][$index] = [
'id' => isset($result[$id]) ? $id : NULL,
}
}
+ private function validateBySavedSearch($entity, array $ids) {
+ $idField = CoreUtil::getIdFieldName($entity['type']);
+ $fetched = civicrm_api4($entity['type'], 'autocomplete', [
+ 'ids' => $ids,
+ 'formName' => 'afform:' . $this->name,
+ 'fieldName' => $entity['name'] . ':' . $idField,
+ ])->indexBy($idField);
+ $validIds = [];
+ // Preserve keys
+ foreach ($ids as $index => $id) {
+ if (isset($fetched[$id])) {
+ $validIds[$index] = $id;
+ }
+ }
+ return $validIds;
+ }
+
/**
* @return array
*/
if (!empty($entity['fields'][$fieldName]['defn'])) {
$defn = \CRM_Utils_JS::decode($entity['fields'][$fieldName]['defn']);
}
- $apiRequest->setCheckPermissions(empty($defn['skip_permissions']));
+ $apiRequest->setCheckPermissions($entity['security'] !== 'FBAC');
$apiRequest->setSavedSearch($defn['saved_search'] ?? NULL);
}
}
var modelProps = {
type: '@',
data: '=',
+ actions: '=',
modelName: '@name',
label: '@',
autofill: '@'
this.$onInit = function() {
var entity = _.pick(this, _.keys(modelProps));
+ entity.actions = entity.actions || {update: true, create: true};
entity.id = null;
this.afForm.registerEntity(entity);
};
}
};
+ ctrl.onSelectExisting = function() {
+ var val = $scope.getSetSelect();
+ var entity = ctrl.afFieldset.modelName;
+ var index = ctrl.getEntityIndex();
+ ctrl.afFieldset.afFormCtrl.loadData(entity, index, val);
+ };
+
// Params for the Afform.submitFile API when uploading a file field
ctrl.getFileUploadParams = function() {
return {
// If there is no Afform entity, get the name of embedded search display
$element.find('[search-name][display-name]').attr('display-name');
};
+ this.getEntity = function() {
+ return this.afFormCtrl.getEntity(this.modelName);
+ };
this.getEntityType = function() {
return this.afFormCtrl.getEntity(this.modelName).type;
};
this.getFormMeta = function getFormMeta() {
return $scope.$parent.meta;
};
- this.loadData = function() {
- var toLoad = 0;
- args = _.assign({}, $scope.$parent.routeParams || {}, $scope.$parent.options || {});
- _.each(schema, function(entity, entityName) {
- if (args[entityName] || entity.autofill) {
- toLoad++;
- }
- });
+ // With no arguments this will prefill the entire form based on url args
+ // With selectedEntity, selectedIndex & selectedId provided this will prefill a single entity
+ this.loadData = function(selectedEntity, selectedIndex, selectedId) {
+ var toLoad = 0,
+ params = {name: ctrl.getFormMeta().name, args: {}};
+ // Load single entity
+ if (selectedEntity) {
+ toLoad = selectedId;
+ params.args[selectedEntity] = {};
+ params.args[selectedEntity][selectedIndex] = selectedId;
+ } else {
+ args = _.assign({}, $scope.$parent.routeParams || {}, $scope.$parent.options || {});
+ _.each(schema, function (entity, entityName) {
+ if (args[entityName] || entity.autofill) {
+ toLoad++;
+ }
+ if (args[entityName] && typeof args[entityName] === 'string') {
+ args[entityName] = args[entityName].split(',');
+ }
+ });
+ params.args = args;
+ }
if (toLoad) {
- crmApi4('Afform', 'prefill', {name: ctrl.getFormMeta().name, args: args})
+ crmApi4('Afform', 'prefill', params)
.then(function(result) {
_.each(result, function(item) {
data[item.name] = data[item.name] || {};
function replaceTokens(str, vars) {
function recurse(stack, values) {
_.each(values, function(value, key) {
- console.log('value:' + value, stack);
if (_.isArray(value) || _.isPlainObject(value)) {
recurse(stack.concat([key]), value);
} else {
-<input class="form-control" id="{{:: fieldId }}" ng-model="getSetSelect" ng-model-options="{getterSetter: true}" crm-autocomplete="$ctrl.defn.entity" crm-autocomplete-params="{formName: 'afform:' + $ctrl.afFieldset.getFormName(), fieldName: $ctrl.afFieldset.modelName + ':' + $ctrl.fieldName}" placeholder="{{:: $ctrl.defn.input_attrs.placeholder }}" >
+<input id="{{:: fieldId }}"
+ class="form-control"
+ ng-disabled="$ctrl.afFieldset.getEntity().actions.update === false"
+ ng-model="getSetSelect"
+ ng-model-options="{getterSetter: true}"
+ crm-autocomplete="$ctrl.defn.entity"
+ crm-autocomplete-params="{formName: 'afform:' + $ctrl.afFieldset.getFormName(), fieldName: $ctrl.afFieldset.modelName + ':' + $ctrl.fieldName}"
+ placeholder="{{:: $ctrl.defn.input_attrs.placeholder }}"
+ ng-change="$ctrl.onSelectExisting()" >