Merge pull request #18076 from MegaphoneJon/better-on-behalf-of-2
[civicrm-core.git] / ext / search / ang / search.module.js
CommitLineData
25523059
CW
1(function(angular, $, _) {
2 "use strict";
3
4 // Shared between router and searchMeta service
5 var searchEntity;
6
7 // Declare module and route/controller/services
8 angular.module('search', CRM.angRequires('search'))
9
10 .config(function($routeProvider) {
11 $routeProvider.when('/:entity', {
12 controller: 'searchRoute',
b0422f12 13 template: '<div id="bootstrap-theme" class="crm-search"><crm-search entity="entity"></crm-search></div>',
25523059
CW
14 reloadOnSearch: false
15 });
16 })
17
18 // Controller binds entity to route
19 .controller('searchRoute', function($scope, $routeParams, $location) {
20 searchEntity = $scope.entity = $routeParams.entity;
21
22 // Changing entity will refresh the angular page
23 $scope.$watch('entity', function(newEntity, oldEntity) {
24 if (newEntity && oldEntity && newEntity !== oldEntity) {
25 $location.url('/' + newEntity);
26 }
27 });
28 })
29
30 .factory('searchMeta', function() {
31 function getEntity(entityName) {
32 if (entityName) {
33 entityName = entityName === true ? searchEntity : entityName;
34 return _.find(CRM.vars.search.schema, {name: entityName});
35 }
36 }
37 function getField(name) {
38 var dotSplit = name.split('.'),
39 joinEntity = dotSplit.length > 1 ? dotSplit[0] : null,
40 fieldName = _.last(dotSplit).split(':')[0],
41 entityName = searchEntity;
27bed3cb
CW
42 // Custom fields contain a dot in their fieldname
43 // If 3 segments, the first is the joinEntity and the last 2 are the custom field
44 if (dotSplit.length === 3) {
45 fieldName = dotSplit[1] + '.' + fieldName;
46 }
47 // If 2 segments, it's ambiguous whether this is a custom field or joined field. Search the main entity first.
48 if (dotSplit.length === 2) {
49 var field = _.find(getEntity(true).fields, {name: dotSplit[0] + '.' + fieldName});
50 if (field) {
51 return field;
52 }
53 }
25523059
CW
54 if (joinEntity) {
55 entityName = _.find(CRM.vars.search.links[entityName], {alias: joinEntity}).entity;
56 }
57 return _.find(getEntity(entityName).fields, {name: fieldName});
58 }
59 return {
60 getEntity: getEntity,
61 getField: getField,
62 parseExpr: function(expr) {
63 var result = {},
64 fieldName = expr,
65 bracketPos = expr.indexOf('(');
66 if (bracketPos >= 0) {
67 fieldName = expr.match(/[A-Z( _]*([\w.:]+)/)[1];
68 result.fn = _.find(CRM.vars.search.functions, {name: expr.substring(0, bracketPos)});
69 }
70 result.field = getField(fieldName);
71 var split = fieldName.split(':'),
f9ee2f07 72 prefixPos = split[0].lastIndexOf(result.field.name);
25523059 73 result.path = split[0];
27bed3cb 74 result.prefix = prefixPos > 0 ? result.path.substring(0, prefixPos) : '';
25523059
CW
75 result.suffix = !split[1] ? '' : ':' + split[1];
76 return result;
77 }
78 };
79 })
80
81 // Reformat an array of objects for compatibility with select2
82 // Todo this probably belongs in core
83 .factory('formatForSelect2', function() {
84 return function(input, key, label, extra) {
85 return _.transform(input, function(result, item) {
86 var formatted = {id: item[key], text: item[label]};
87 if (extra) {
88 _.merge(formatted, _.pick(item, extra));
89 }
90 result.push(formatted);
91 }, []);
92 };
93 });
94
95})(angular, CRM.$, CRM._);