[CLAMP-1] Initial ONAP CLAMP seed code commit
[clamp.git] / src / main / resources / META-INF / resources / designer / lib / angucomplete.js
1 /**
2  * Angucomplete
3  * Autocomplete directive for AngularJS
4  * By Daryl Rowland
5  */
6
7 angular.module('angucomplete', [] )
8     .directive('angucomplete', function ($parse, $http, $sce, $timeout) {
9     return {
10         restrict: 'EA',
11         scope: {
12             "id": "@id",
13             "placeholder": "@placeholder",
14             "selectedObject": "=selectedobject",
15             "url": "@url",
16             "dataField": "@datafield",
17             "titleField": "@titlefield",
18             "descriptionField": "@descriptionfield",
19             "imageField": "@imagefield",
20             "imageUri": "@imageuri",
21             "inputClass": "@inputclass",
22             "userPause": "@pause",
23             "localData": "=localdata",
24             "searchFields": "@searchfields",
25             "minLengthUser": "@minlength",
26             "matchClass": "@matchclass"
27         },
28         template: '<div class="angucomplete-holder"><input id="{{id}}_value" ng-model="searchStr" type="text" placeholder="{{placeholder}}" class="{{inputClass}}" onmouseup="this.select();" ng-focus="resetHideResults()" ng-blur="hideResults()" /><div id="{{id}}_dropdown" class="angucomplete-dropdown" style="height:300px;overflow:auto;" ng-if="showDropdown"><div class="angucomplete-searching" ng-show="searching">Searching...</div><div class="angucomplete-searching" ng-show="!searching && (!results || results.length == 0)">No results found</div><div class="angucomplete-row" ng-repeat="result in results" ng-click="selectResult(result)" ng-mouseover="hoverRow()" ng-class="{\'angucomplete-selected-row\': $index == currentIndex}"><div ng-if="imageField" class="angucomplete-image-holder"><img ng-if="result.image && result.image != \'\'" ng-src="{{result.image}}" class="angucomplete-image"/><div ng-if="!result.image && result.image != \'\'" class="angucomplete-image-default"></div></div><div class="angucomplete-title" ng-if="matchClass" ng-bind-html="result.title"></div><div class="angucomplete-title" ng-if="!matchClass">{{ result.title }}</div><div ng-if="result.description && result.description != \'\'" class="angucomplete-description">{{result.description}}</div></div></div></div>',
29
30         link: function($scope, elem, attrs) {
31             $scope.lastSearchTerm = null;
32             $scope.currentIndex = null;
33             $scope.justChanged = false;
34             $scope.searchTimer = null;
35             $scope.hideTimer = null;
36             $scope.searching = false;
37             $scope.pause = 500;
38             $scope.minLength = 3;
39             $scope.searchStr = null;
40
41             if ($scope.minLengthUser && $scope.minLengthUser != "") {
42                 $scope.minLength = $scope.minLengthUser;
43             }
44
45             if ($scope.userPause) {
46                 $scope.pause = $scope.userPause;
47             }
48
49             isNewSearchNeeded = function(newTerm, oldTerm) {
50                 return newTerm.length >= $scope.minLength && newTerm != oldTerm
51             }
52
53             $scope.processResults = function(responseData, str) {
54                 if (responseData && responseData.length > 0) {
55                     $scope.results = [];
56
57                     var titleFields = [];
58                     if ($scope.titleField && $scope.titleField != "") {
59                         titleFields = $scope.titleField.split(",");
60                     }
61
62                     for (var i = 0; i < responseData.length; i++) {
63                         // Get title variables
64                         var titleCode = [];
65
66                         for (var t = 0; t < titleFields.length; t++) {
67                             titleCode.push(responseData[i][titleFields[t]]);
68                         }
69
70                         var description = "";
71                         if ($scope.descriptionField) {
72                             description = responseData[i][$scope.descriptionField];
73                         }
74
75                         var imageUri = "";
76                         if ($scope.imageUri) {
77                             imageUri = $scope.imageUri;
78                         }
79
80                         var image = "";
81                         if ($scope.imageField) {
82                             image = imageUri + responseData[i][$scope.imageField];
83                         }
84
85                         var text = titleCode.join(' ');
86                         if ($scope.matchClass) {
87                             var re = new RegExp(str, 'i');
88                             var strPart = text.match(re)[0];
89                             text = $sce.trustAsHtml(text.replace(re, '<span class="'+ $scope.matchClass +'">'+ strPart +'</span>'));
90                         }
91
92                         var resultRow = {
93                             title: text,
94                             description: description,
95                             image: image,
96                             originalObject: responseData[i]
97                         }
98
99                         $scope.results[$scope.results.length] = resultRow;
100                     }
101
102
103                 } else {
104                     $scope.results = [];
105                 }
106             }
107
108             $scope.searchTimerComplete = function(str) {
109                 // Begin the search
110
111                 if (str.length >= $scope.minLength) {
112                     if ($scope.localData) {
113                         var searchFields = $scope.searchFields.split(",");
114
115                         var matches = [];
116
117                         for (var i = 0; i < $scope.localData.length; i++) {
118                             var match = false;
119
120                             for (var s = 0; s < searchFields.length; s++) {
121                                 match = match || (typeof $scope.localData[i][searchFields[s]] === 'string' && typeof str === 'string' && $scope.localData[i][searchFields[s]].toLowerCase().indexOf(str.toLowerCase()) >= 0);
122                             }
123
124                             if (match) {
125                                 matches[matches.length] = $scope.localData[i];
126                             }
127                         }
128
129                         $scope.searching = false;
130                         $scope.processResults(matches, str);
131
132                     } else {
133                         $http.get($scope.url + str, {}).
134                             success(function(responseData, status, headers, config) {
135                                 $scope.searching = false;
136                                 $scope.processResults((($scope.dataField) ? responseData[$scope.dataField] : responseData ), str);
137                             }).
138                             error(function(data, status, headers, config) {
139                                 console.log("error");
140                             });
141                     }
142                 }
143             }
144
145             $scope.hideResults = function() {
146                 $scope.hideTimer = $timeout(function() {
147                     $scope.showDropdown = false;
148                 }, $scope.pause);
149             };
150
151             $scope.resetHideResults = function() {
152                 if($scope.hideTimer) {
153                     $timeout.cancel($scope.hideTimer);
154                 };
155             };
156
157             $scope.hoverRow = function(index) {
158                 $scope.currentIndex = index;
159             }
160
161             $scope.keyPressed = function(event) {
162                 if (!(event.which == 38 || event.which == 40 || event.which == 13)) {
163                     if (!$scope.searchStr || $scope.searchStr == "") {
164                         $scope.showDropdown = false;
165                         $scope.lastSearchTerm = null
166                     } else if (isNewSearchNeeded($scope.searchStr, $scope.lastSearchTerm)) {
167                         $scope.lastSearchTerm = $scope.searchStr
168                         $scope.showDropdown = true;
169                         $scope.currentIndex = -1;
170                         $scope.results = [];
171
172                         if ($scope.searchTimer) {
173                             $timeout.cancel($scope.searchTimer);
174                         }
175
176                         $scope.searching = true;
177
178                         $scope.searchTimer = $timeout(function() {
179                             $scope.searchTimerComplete($scope.searchStr);
180                         }, $scope.pause);
181                     }
182                 } else {
183                     event.preventDefault();
184                 }
185             }
186
187             $scope.selectResult = function(result) {
188                 if ($scope.matchClass) {
189                     result.title = result.title.toString().replace(/(<([^>]+)>)/ig, '');
190                 }
191                 $scope.searchStr = $scope.lastSearchTerm = result.title;
192                 $scope.selectedObject = result;
193                 $scope.showDropdown = false;
194                 $scope.results = [];
195                 //$scope.$apply();
196             }
197
198             var inputField = elem.find('input');
199
200             inputField.on('keyup', $scope.keyPressed);
201
202             elem.on("keyup", function (event) {
203                 if(event.which === 40) {
204                     if ($scope.results && ($scope.currentIndex + 1) < $scope.results.length) {
205                         $scope.currentIndex ++;
206                         $scope.$apply();
207                         event.preventDefault;
208                         event.stopPropagation();
209                     }
210
211                     $scope.$apply();
212                 } else if(event.which == 38) {
213                     if ($scope.currentIndex >= 1) {
214                         $scope.currentIndex --;
215                         $scope.$apply();
216                         event.preventDefault;
217                         event.stopPropagation();
218                     }
219
220                 } else if (event.which == 13) {
221                     if ($scope.results && $scope.currentIndex >= 0 && $scope.currentIndex < $scope.results.length) {
222                         $scope.selectResult($scope.results[$scope.currentIndex]);
223                         $scope.$apply();
224                         event.preventDefault;
225                         event.stopPropagation();
226                     } else {
227                         $scope.results = [];
228                         $scope.$apply();
229                         event.preventDefault;
230                         event.stopPropagation();
231                     }
232
233                 } else if (event.which == 27) {
234                     $scope.results = [];
235                     $scope.showDropdown = false;
236                     $scope.$apply();
237                 } else if (event.which == 8) {
238                     $scope.selectedObject = null;
239                     $scope.$apply();
240                 }
241             });
242
243         }
244     };
245 });
246