-<fieldset id="crm-search-build-functions" class="crm-search-select-fields">
- <div>
- <!-- Must use track by $index with an array of primitives, and manually refresh this loop when indexes change -->
- <fieldset ng-repeat="col in $ctrl.savedSearch.api_params.select track by $index" ng-if="!$ctrl.isPseudoField(col)">
- <crm-search-function class="form-inline" mode="select" expr="$ctrl.savedSearch.api_params.select[$index]"></crm-search-function>
- </fieldset>
- </div>
+<fieldset class="crm-search-select-fields">
+ <crm-search-admin-fields></crm-search-admin-fields>
</fieldset>
// Deletes an item from an array param
this.clearParam = function(name, idx) {
- if (name === 'select') {
- // Function selectors use `ng-repeat` with `track by $index` so must be refreshed when splicing the array
- ctrl.hideFuncitons();
- }
ctrl.savedSearch.api_params[name].splice(idx, 1);
};
- this.hideFuncitons = function() {
- $scope.controls.showFunctions = false;
- };
-
function onChangeSelect(newSelect, oldSelect) {
// When removing a column from SELECT, also remove from ORDER BY & HAVING
_.each(_.difference(oldSelect, newSelect), function(col) {
return {results: ctrl.getSelectFields()};
};
+ this.fieldsForSelect = function() {
+ return {
+ results: ctrl.getAllFields(':label', ['Field', 'Custom', 'Extra', 'Pseudo'], (key) => {
+ ctrl.savedSearch.api_params.select.includes(key);
+ })
+ };
+ };
+
this.getAllFields = function(suffix, allowedTypes, disabledIf, topJoin) {
disabledIf = disabledIf || _.noop;
allowedTypes = allowedTypes || ['Field', 'Custom', 'Extra', 'Filter'];
--- /dev/null
+(function(angular, $, _) {
+ "use strict";
+
+ angular.module('crmSearchAdmin').component('crmSearchAdminFields', {
+ bindings: {
+ },
+ require: {
+ crmSearchAdmin: '^crmSearchAdmin'
+ },
+ templateUrl: '~/crmSearchAdmin/crmSearchAdminFields.html',
+ controller: function ($scope, $element) {
+ var ts = $scope.ts = CRM.ts('org.civicrm.search_kit'),
+ ctrl = this;
+
+ // savedSearch.api_params.select is an array of strings.
+ // ui-sortable (and angularJs loops in general) don't work well with primitives
+ // So this controller converts the strings into objects and maintains 2-way sync between
+ // the two arrays.
+ this.select = [];
+
+ $scope.$watchCollection('$ctrl.crmSearchAdmin.savedSearch.api_params.select', function(flatSelect) {
+ ctrl.select.length = flatSelect.length;
+ flatSelect.forEach((key, index) => {
+ ctrl.select[index] = ctrl.select[index] || {};
+ ctrl.select[index].key = key;
+ ctrl.select[index].label = ctrl.crmSearchAdmin.getFieldLabel(key);
+ ctrl.select[index].isPseudoField = ctrl.crmSearchAdmin.isPseudoField(key);
+ });
+ });
+
+ $scope.$watch('$ctrl.select', function(selectObject, oldSelect) {
+ if (oldSelect && oldSelect.length && selectObject) {
+ ctrl.crmSearchAdmin.savedSearch.api_params.select.length = selectObject.length;
+ selectObject.forEach((item, index) => {
+ ctrl.crmSearchAdmin.savedSearch.api_params.select[index] = item.key;
+ });
+ }
+ }, true);
+
+ // Drag-n-drop settings for reordering search fields
+ this.sortableOptions = {
+ containment: '.crm-search-select-fields',
+ axis: 'y',
+ forcePlaceholderSize: true,
+ update: function(e, ui) {
+ // Don't allow items to be moved to position 0 if locked
+ if (!ui.item.sortable.dropindex && ctrl.crmSearchAdmin.groupExists) {
+ ui.item.sortable.cancel();
+ }
+ }
+ };
+
+ }
+ });
+
+})(angular, CRM.$, CRM._);
--- /dev/null
+<div ng-model="$ctrl.select" ui-sortable="$ctrl.sortableOptions">
+ <fieldset ng-repeat="col in $ctrl.select" class="crm-draggable">
+ <i class="crm-i fa-arrows crm-search-move-icon"></i>
+ <crm-search-function ng-if="!col.isPseudoField" class="form-inline" mode="select" expr="col.key"></crm-search-function>
+ <label ng-if="col.isPseudoField">{{:: col.label }}</label>
+ <button type="button" class="btn-xs pull-right" ng-if="$ctrl.select.length > 1" ng-click="$ctrl.crmSearchAdmin.clearParam('select', $index)" title="{{:: ts('Remove') }}">
+ <i class="crm-i fa-ban"></i>
+ </button>
+ </fieldset>
+</div>
+<input class="form-control crm-action-menu fa-plus collapsible-optgroups"
+ crm-ui-select="::{data: $ctrl.crmSearchAdmin.fieldsForSelect, placeholder: ts('Add')}"
+ on-crm-ui-select="$ctrl.crmSearchAdmin.addParam('select', selection)" >
if (!ui.item.sortable.dropindex && ctrl.crmSearchAdmin.groupExists) {
ui.item.sortable.cancel();
}
- // Function selectors use `ng-repeat` with `track by $index` so must be refreshed when rearranging the array
- ctrl.crmSearchAdmin.hideFuncitons();
}
};
$scope.fieldsForSelect = function() {
- return {results: ctrl.crmSearchAdmin.getAllFields(':label', ['Field', 'Custom', 'Extra', 'Pseudo'], function(key) {
- return _.contains(ctrl.search.api_params.select, key);
- })
- };
+ return ctrl.crmSearchAdmin.fieldsForSelect();
};
$scope.addColumn = function(col) {
</th>
<th class="form-inline text-right">
<input class="form-control crm-action-menu fa-plus collapsible-optgroups"
- crm-ui-select="::{data: fieldsForSelect, placeholder: ts('Add'), width: '80px', containerCss: {minWidth: '80px'}, dropdownCss: {width: '300px'}}"
+ crm-ui-select="::{data: fieldsForSelect, placeholder: ' ', width: '48px', containerCss: {minWidth: '48px'}, dropdownCss: {width: '300px'}}"
on-crm-ui-select="addColumn(selection)" >
</th>
</tr>