+++ /dev/null
-(function(angular, $, _) {
- // Example usage: <af-form><af-entity name="Person" type="Contact" /> ... <fieldset af-fieldset="Person> ... </fieldset></af-form>
- angular.module('af').directive('afEntity', function() {
- // Whitelist of all allowed properties of an af-fieldset
- // (at least the ones we care about client-side - other's can be added for server-side processing and we'll just ignore them)
- var modelProps = {
- type: '@',
- data: '=',
- modelName: '@name',
- label: '@',
- autofill: '@'
- };
- return {
- restrict: 'E',
- require: '^afForm',
- scope: modelProps,
- link: function($scope, $el, $attr, afFormCtrl) {
- var ts = $scope.ts = CRM.ts('afform'),
- entity = _.pick($scope, _.keys(modelProps));
- entity.id = null;
- afFormCtrl.registerEntity(entity);
- // $scope.$watch('afEntity', function(newValue){$scope.myOptions = newValue;});
- }
- };
- });
-})(angular, CRM.$, CRM._);
+++ /dev/null
-(function(angular, $, _) {
- var id = 0;
- // Example usage: <div af-fieldset="myModel"><af-field name="do_not_email" /></div>
- angular.module('af').directive('afField', function(crmApi4) {
- return {
- restrict: 'E',
- require: ['^^afForm', '^^afFieldset', '?^^afJoin', '?^^afRepeatItem'],
- templateUrl: '~/af/afField.html',
- scope: {
- fieldName: '@name',
- defn: '='
- },
- link: function($scope, $el, $attr, ctrls) {
- var ts = $scope.ts = CRM.ts('afform'),
- closestController = $($el).closest('[af-fieldset],[af-join],[af-repeat-item]'),
- afForm = ctrls[0],
- boolOptions = [{id: true, label: ts('Yes')}, {id: false, label: ts('No')}],
- // Only used for is_primary radio button
- noOptions = [{id: true, label: ''}];
- $scope.dataProvider = closestController.is('[af-repeat-item]') ? ctrls[3] : ctrls[2] || ctrls[1];
- $scope.fieldId = afForm.getFormMeta().name + '-' + $scope.fieldName + '-' + id++;
-
- $el.addClass('af-field-type-' + _.kebabCase($scope.defn.input_type));
-
- $scope.getOptions = function() {
- return $scope.defn.options || ($scope.fieldName === 'is_primary' && $scope.defn.input_type === 'Radio' ? noOptions : boolOptions);
- };
-
- $scope.select2Options = function() {
- return {
- results: _.transform($scope.getOptions(), function(result, opt) {
- result.push({id: opt.id, text: opt.label});
- }, [])
- };
- };
-
- // is_primary field - watch others in this afRepeat block to ensure only one is selected
- if ($scope.fieldName === 'is_primary' && 'repeatIndex' in $scope.dataProvider) {
- $scope.$watch('dataProvider.afRepeat.getEntityController().getData()', function (items, prev) {
- var index = $scope.dataProvider.repeatIndex;
- // Set first item to primary if there isn't a primary
- if (items && !index && !_.find(items, 'is_primary')) {
- $scope.dataProvider.getFieldData().is_primary = true;
- }
- // Set this item to not primary if another has been selected
- if (items && prev && items.length === prev.length && items[index].is_primary && prev[index].is_primary &&
- _.filter(items, 'is_primary').length > 1
- ) {
- $scope.dataProvider.getFieldData().is_primary = false;
- }
- }, true);
- }
-
- // ChainSelect - watch control field & reload options as needed
- if ($scope.defn.input_type === 'ChainSelect') {
- $scope.$watch('dataProvider.getFieldData()[defn.input_attrs.controlField]', function(val) {
- if (val) {
- var params = {
- where: [['name', '=', $scope.fieldName]],
- select: ['options'],
- loadOptions: ['id', 'label'],
- values: {}
- };
- params.values[$scope.defn.input_attrs.controlField] = val;
- crmApi4($scope.dataProvider.getEntityType(), 'getFields', params, 0)
- .then(function(data) {
- $scope.defn.options = data.options;
- });
- }
- });
- }
- }
- };
- });
-})(angular, CRM.$, CRM._);
--- /dev/null
+(function(angular, $, _) {
+ // Whitelist of all allowed properties of an af-fieldset
+ // (at least the ones we care about client-side - other's can be added for server-side processing and we'll just ignore them)
+ var modelProps = {
+ type: '@',
+ data: '=',
+ modelName: '@name',
+ label: '@',
+ autofill: '@'
+ };
+ // Example usage: <af-form><af-entity name="Person" type="Contact" /> ... <fieldset af-fieldset="Person"> ... </fieldset></af-form>
+ angular.module('af').component('afEntity', {
+ require: {afForm: '^afForm'},
+ bindings: modelProps,
+ controller: function() {
+
+ this.$onInit = function() {
+ var entity = _.pick(this, _.keys(modelProps));
+ entity.id = null;
+ this.afForm.registerEntity(entity);
+ };
+ }
+
+ });
+})(angular, CRM.$, CRM._);
--- /dev/null
+(function(angular, $, _) {
+ var id = 0;
+ // Example usage: <div af-fieldset="myModel"><af-field name="do_not_email" /></div>
+ angular.module('af').component('afField', {
+ require: {
+ afFieldset: '^^afFieldset',
+ afJoin: '?^^afJoin',
+ afRepeatItem: '?^^afRepeatItem'
+ },
+ templateUrl: '~/af/afField.html',
+ bindings: {
+ fieldName: '@name',
+ defn: '='
+ },
+ controller: function($scope, $element, crmApi4) {
+ var ts = $scope.ts = CRM.ts('afform'),
+ ctrl = this,
+ boolOptions = [{id: true, label: ts('Yes')}, {id: false, label: ts('No')}],
+ // Only used for is_primary radio button
+ noOptions = [{id: true, label: ''}];
+
+ this.$onInit = function() {
+ var closestController = $($element).closest('[af-fieldset],[af-join],[af-repeat-item]');
+ $scope.dataProvider = closestController.is('[af-repeat-item]') ? ctrl.afRepeatItem : ctrl.afJoin || ctrl.afFieldset;
+ $scope.fieldId = ctrl.fieldName + '-' + id++;
+
+ $element.addClass('af-field-type-' + _.kebabCase(ctrl.defn.input_type));
+
+ // is_primary field - watch others in this afRepeat block to ensure only one is selected
+ if (ctrl.fieldName === 'is_primary' && 'repeatIndex' in $scope.dataProvider) {
+ $scope.$watch('dataProvider.afRepeat.getEntityController().getData()', function (items, prev) {
+ var index = $scope.dataProvider.repeatIndex;
+ // Set first item to primary if there isn't a primary
+ if (items && !index && !_.find(items, 'is_primary')) {
+ $scope.dataProvider.getFieldData().is_primary = true;
+ }
+ // Set this item to not primary if another has been selected
+ if (items && prev && items.length === prev.length && items[index].is_primary && prev[index].is_primary &&
+ _.filter(items, 'is_primary').length > 1
+ ) {
+ $scope.dataProvider.getFieldData().is_primary = false;
+ }
+ }, true);
+ }
+
+ // ChainSelect - watch control field & reload options as needed
+ if (ctrl.defn.input_type === 'ChainSelect') {
+ $scope.$watch('dataProvider.getFieldData()[defn.input_attrs.controlField]', function(val) {
+ if (val) {
+ var params = {
+ where: [['name', '=', ctrl.fieldName]],
+ select: ['options'],
+ loadOptions: ['id', 'label'],
+ values: {}
+ };
+ params.values[ctrl.defn.input_attrs.controlField] = val;
+ crmApi4($scope.dataProvider.getEntityType(), 'getFields', params, 0)
+ .then(function(data) {
+ ctrl.defn.options = data.options;
+ });
+ }
+ });
+ }
+
+ };
+
+ $scope.getOptions = function () {
+ return ctrl.defn.options || (ctrl.fieldName === 'is_primary' && ctrl.defn.input_type === 'Radio' ? noOptions : boolOptions);
+ };
+
+ $scope.select2Options = function() {
+ return {
+ results: _.transform($scope.getOptions(), function(result, opt) {
+ result.push({id: opt.id, text: opt.label});
+ }, [])
+ };
+ };
+
+ }
+ });
+})(angular, CRM.$, CRM._);
-<label class="crm-af-field-label" ng-if="defn.label" for="{{ fieldId }}">
- {{ defn.label }}
+<label class="crm-af-field-label" ng-if="$ctrl.defn.label" for="{{:: fieldId }}">
+ {{:: $ctrl.defn.label }}
</label>
-<p class="crm-af-field-help-pre" ng-if="defn.help_pre">{{ defn.help_pre }}</p>
-<div class="crm-af-field" ng-include="'~/af/fields/' + defn.input_type + '.html'"></div>
-<p class="crm-af-field-help-post" ng-if="defn.help_post">{{ defn.help_post }}</p>
+<p class="crm-af-field-help-pre" ng-if="$ctrl.defn.help_pre">{{:: $ctrl.defn.help_pre }}</p>
+<div class="crm-af-field" ng-include="'~/af/fields/' + $ctrl.defn.input_type + '.html'"></div>
+<p class="crm-af-field-help-post" ng-if="$ctrl.defn.help_post">{{:: $ctrl.defn.help_post }}</p>
}
};
})
+ // @internal directive used within the afRepeat directive, invoked once per iteration
.directive('afRepeatItem', function() {
return {
restrict: 'A',
<div af-repeat-item="item" repeat-index="$index" ng-repeat="item in getItems()">
- <ng-transclude />
+ <ng-transclude></ng-transclude>
<button crm-icon="fa-ban" class="btn btn-xs af-repeat-remove-btn" ng-if="canRemove()" ng-click="removeItem($index)"></button>
</div>
<button crm-icon="{{ addIcon || 'fa-plus' }}" class="btn btn-sm af-repeat-add-btn" ng-if="canAdd()" ng-click="addItem()">{{ addLabel }}</button>
-<input crm-ui-select="{data: select2Options, multiple: defn.input_attrs.multiple, placeholder: defn.input_attrs.placeholder}" id="{{ fieldId }}" ng-model="dataProvider.getFieldData()[fieldName]" />
+<input crm-ui-select="{data: select2Options, multiple: $ctrl.defn.input_attrs.multiple, placeholder: $ctrl.defn.input_attrs.placeholder}" id="{{:: fieldId }}" ng-model="dataProvider.getFieldData()[$ctrl.fieldName]" />
-<ul class="crm-checkbox-list" id="{{ fieldId }}" ng-if="defn.options">
- <li ng-repeat="opt in defn.options track by opt.id" >
- <input type="checkbox" checklist-model="dataProvider.getFieldData()[fieldName]" id="{{ fieldId + opt.id }}" checklist-value="opt.id" />
+<ul class="crm-checkbox-list" id="{{ fieldId }}" ng-if="$ctrl.defn.options">
+ <li ng-repeat="opt in $ctrl.defn.options track by opt.id" >
+ <input type="checkbox" checklist-model="dataProvider.getFieldData()[$ctrl.fieldName]" id="{{ fieldId + opt.id }}" checklist-value="opt.id" />
<label for="{{ fieldId + opt.id }}">{{ opt.label }}</label>
</li>
</ul>
-<input type="checkbox" ng-if="!defn.options" id="{{ fieldId }}" ng-model="dataProvider.getFieldData()[fieldName]" />
+<input type="checkbox" ng-if="!$ctrl.defn.options" id="{{ fieldId }}" ng-model="dataProvider.getFieldData()[$ctrl.fieldName]" />
-<input crm-ui-datepicker="defn.input_attrs" id="{{ fieldId }}" ng-model="dataProvider.getFieldData()[fieldName]" />
+<input crm-ui-datepicker="$ctrl.defn.input_attrs" id="{{ fieldId }}" ng-model="dataProvider.getFieldData()[$ctrl.fieldName]" />
-<input class="crm-form-text" type="number" id="{{ fieldId }}" ng-model="dataProvider.getFieldData()[fieldName]" placeholder="{{ defn.input_attrs.placeholder }}" />
+<input class="crm-form-text" type="number" id="{{ fieldId }}" ng-model="dataProvider.getFieldData()[$ctrl.fieldName]" placeholder="{{ $ctrl.defn.input_attrs.placeholder }}" />
<label ng-repeat="opt in getOptions() track by opt.id" >
- <input class="crm-form-radio" type="radio" ng-model="dataProvider.getFieldData()[fieldName]" ng-value="opt.id" />
+ <input class="crm-form-radio" type="radio" ng-model="dataProvider.getFieldData()[$ctrl.fieldName]" ng-value="opt.id" />
{{ opt.label }}
</label>
-<textarea crm-ui-richtext id="{{ fieldId }}" ng-model="dataProvider.getFieldData()[fieldName]" ></textarea>
+<textarea crm-ui-richtext id="{{ fieldId }}" ng-model="dataProvider.getFieldData()[$ctrl.fieldName]" ></textarea>
-<input crm-ui-select="{data: select2Options, multiple: defn.input_attrs.multiple, placeholder: defn.input_attrs.placeholder}" id="{{ fieldId }}" ng-model="dataProvider.getFieldData()[fieldName]" />
+<input crm-ui-select="{data: select2Options, multiple: $ctrl.defn.input_attrs.multiple, placeholder: $ctrl.defn.input_attrs.placeholder}" id="{{:: fieldId }}" ng-model="dataProvider.getFieldData()[$ctrl.fieldName]" />
-<input class="crm-form-text" type="text" id="{{ fieldId }}" ng-model="dataProvider.getFieldData()[fieldName]" placeholder="{{ defn.input_attrs.placeholder }}" />
+<input class="crm-form-text" type="text" id="{{:: fieldId }}" ng-model="dataProvider.getFieldData()[$ctrl.fieldName]" placeholder="{{ $ctrl.defn.input_attrs.placeholder }}" />
-<textarea class="crm-form-textarea" id="{{ fieldId }}" ng-model="dataProvider.getFieldData()[fieldName]" ></textarea>
+<textarea class="crm-form-textarea" id="{{:: fieldId }}" ng-model="dataProvider.getFieldData()[$ctrl.fieldName]" ></textarea>