angular-smart-search 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 97d4972c061407bff51f20fe716975942dceacf4
4
- data.tar.gz: 3a31a712a5b94be653c7df85f9584ca49830a6ec
3
+ metadata.gz: 04cb4a6f9b79c9b5ea2f7eb89b4596550f584c30
4
+ data.tar.gz: 12e620cc49c2ccc19b7cff616eae6af86de53cdf
5
5
  SHA512:
6
- metadata.gz: f406901f8fbf87ac665209fa59b9f583dcde46b650ae61c63d2316343191b97327a897f3ef6aa30959bed5985f77213d2c9eaf50c438399d4b9eefa5caac3e0b
7
- data.tar.gz: bfc71b27b7c1a7f5cbc74d68a53be0d4050f8ae081cdc782f101daddd49e55acc11c5ade14cbf980e4cf40f18635253acb43cd316d67b734b9b761bcc7c8d7e1
6
+ metadata.gz: 7cc5b239350f9d22de67291d61a3641d82614210ddcefd1aab076a8416c7c7a4062695ac66d6cccb2d5dcec2aee34db1574235b0a2225c33cf0287ce51239d75
7
+ data.tar.gz: 41194c15087798de012a842e53ba4033d0452658f7cf8ff6c9a42c722d929ae51204d1ddbffb9620ca1925709274f096557c45815007976777ea3cdff9bae247
@@ -1,5 +1,5 @@
1
1
  // author: Samuel Mueller
2
- // version: 0.0.5
2
+ // version: 0.0.6
3
3
  // license: MIT
4
4
  // homepage: http://github.com/ssmm/angular-smart-search
5
5
  (function() {
@@ -26,18 +26,27 @@
26
26
  return {
27
27
  restrict: "A",
28
28
  scope: true,
29
- replace: true,
30
- template: templateFactory(),
31
29
  compile: function(element, attributes, transclude) {
32
- var id_field;
30
+ var detailOverlay, id_field, template;
33
31
 
32
+ if (attributes.detailOverlay) {
33
+ detailOverlay = jQuery("#" + attributes.detailOverlay);
34
+ if (!detailOverlay[0]) {
35
+ detailOverlay = void 0;
36
+ }
37
+ }
38
+ template = angular.element(templateFactory.getTemplate(angular.isDefined(detailOverlay)));
39
+ if (detailOverlay) {
40
+ angular.element(template.find("detail-overlay")).append(detailOverlay.html());
41
+ }
42
+ element.replaceWith(template);
34
43
  id_field = angular.element("<input ng-model='result.id' type='text' style='width: 30px; display: none;'>");
35
44
  id_field.attr("id", attributes.id);
36
45
  id_field.attr("name", attributes.name);
37
46
  element.append(id_field);
38
47
  return {
39
48
  post: function($scope, $element, $attributes) {
40
- var allowedFormats, input, outerQueryTimeout, overlay, queryState, service;
49
+ var allowedFormats, detailOverlayTrigger, hideOverlay, outerQueryTimeout, queryState, quickQueryInput, searchInput, searchOverlay, service, showOverlay;
41
50
 
42
51
  queryState = new QueryState();
43
52
  $scope.queryState = queryState;
@@ -48,18 +57,35 @@
48
57
  $scope.result = angular.fromJson($attributes.init)[0];
49
58
  $scope.queryState.setTo("successful");
50
59
  }
51
- input = $element.find("[queryfield]");
52
- overlay = $element.children("[overlay]");
53
- $scope.show = function() {
54
- var position;
55
-
56
- position = input.position();
57
- overlay.css("top", position.top - padding);
58
- overlay.css("left", position.left - padding);
59
- return overlay.show("fade");
60
+ quickQueryInput = $element.find("[quick-query-input]");
61
+ searchInput = $element.find("[search-input]");
62
+ detailOverlayTrigger = $element.find("[detail-overlay-trigger]");
63
+ searchOverlay = $element.children("search-overlay");
64
+ detailOverlay = $element.children("detail-overlay");
65
+ showOverlay = function(overlay, origin, action) {
66
+ overlay.css("top", origin.top - padding);
67
+ overlay.css("left", origin.left - padding);
68
+ return overlay.show("fade", action);
69
+ };
70
+ $scope.showSearchOverlay = function() {
71
+ return showOverlay(searchOverlay, quickQueryInput.position(), function() {
72
+ return searchInput.focus();
73
+ });
74
+ };
75
+ $scope.showDetailOverlay = function() {
76
+ $scope.item = $scope.result;
77
+ return showOverlay(detailOverlay, detailOverlayTrigger.position());
60
78
  };
61
- $scope.hide = function() {
62
- return overlay.hide("fade");
79
+ hideOverlay = function(overlay, action) {
80
+ return overlay.hide("fade", action);
81
+ };
82
+ $scope.hideSearchOverlay = function() {
83
+ return hideOverlay(searchOverlay, function() {
84
+ return quickQueryInput.focus();
85
+ });
86
+ };
87
+ $scope.hideDetailOverlay = function() {
88
+ return hideOverlay(detailOverlay);
63
89
  };
64
90
  $scope.search = function(query) {
65
91
  return $http.get("" + service + ".json?fulltext=" + query).success(function(data) {
@@ -70,7 +96,7 @@
70
96
  $scope.pick = function(item) {
71
97
  queryState.setTo("successful");
72
98
  $scope.result = item;
73
- return $scope.hide();
99
+ return $scope.hideSearchOverlay();
74
100
  };
75
101
  $scope.hover = function(item) {
76
102
  return $scope.currentItem = item;
@@ -78,26 +104,32 @@
78
104
  outerQueryTimeout = null;
79
105
  return $scope.outerQueryChanged = function(query) {
80
106
  window.clearTimeout(outerQueryTimeout);
81
- query = searchQueryFactory(query, allowedFormats);
82
- if (query) {
83
- queryState.setTo("changed");
84
- queryState.query = query;
85
- return outerQueryTimeout = window.setTimeout(function() {
86
- queryState.setTo("pending");
87
- $http.get("" + service + ".json?" + query.format.name + "=" + query.query).success(function(data) {
88
- if (data[0] && data[0].id) {
89
- queryState.setTo("successful");
90
- return $scope.result = data[0];
91
- } else {
92
- return queryState.setTo("unsuccessful");
93
- }
94
- }).error(function() {
95
- return queryState.setTo("error");
96
- });
97
- return $scope.$apply();
98
- }, 1200);
107
+ if (!query) {
108
+ if ($scope.result) {
109
+ return queryState.setTo("successful");
110
+ }
99
111
  } else {
100
- return queryState.setTo("invalid-format");
112
+ query = searchQueryFactory(query, allowedFormats);
113
+ if (query) {
114
+ queryState.setTo("changed");
115
+ queryState.query = query;
116
+ return outerQueryTimeout = window.setTimeout(function() {
117
+ queryState.setTo("pending");
118
+ $http.get("" + service + ".json?" + query.format.name + "=" + query.query).success(function(data) {
119
+ if (data[0] && data[0].id) {
120
+ queryState.setTo("successful");
121
+ return $scope.result = data[0];
122
+ } else {
123
+ return queryState.setTo("unsuccessful");
124
+ }
125
+ }).error(function() {
126
+ return queryState.setTo("error");
127
+ });
128
+ return $scope.$apply();
129
+ }, 1200);
130
+ } else {
131
+ return queryState.setTo("invalid-format");
132
+ }
101
133
  }
102
134
  };
103
135
  }
@@ -107,6 +139,45 @@
107
139
  }
108
140
  ]);
109
141
 
142
+ angular.module("angular-smart-search").provider("markupStore", [
143
+ function() {
144
+ var infoIconClass, overlayClass, searchIconClass, successIconClass;
145
+
146
+ successIconClass = "icon-info-sign icon-large";
147
+ infoIconClass = "icon-info-sign";
148
+ searchIconClass = "icon-search";
149
+ overlayClass = "smart-search-overlay";
150
+ this.setSuccessIconClass = function(attr) {
151
+ return successIconClass = attr;
152
+ };
153
+ this.setInfoIconClass = function(attr) {
154
+ return infoIconClass = attr;
155
+ };
156
+ this.setSearchIconClass = function(attr) {
157
+ return searchIconClass = attr;
158
+ };
159
+ this.setOverlayClass = function(attr) {
160
+ return overlayClass = attr;
161
+ };
162
+ return this.$get = function() {
163
+ return {
164
+ successIconClass: function() {
165
+ return successIconClass;
166
+ },
167
+ infoIconClass: function() {
168
+ return infoIconClass;
169
+ },
170
+ searchIconClass: function() {
171
+ return searchIconClass;
172
+ },
173
+ overlayClass: function() {
174
+ return overlayClass;
175
+ }
176
+ };
177
+ };
178
+ }
179
+ ]);
180
+
110
181
  angular.module("angular-smart-search").provider("searchQueryFactory", [
111
182
  function() {
112
183
  var Query, detectFormat, formats;
@@ -121,7 +192,7 @@
121
192
 
122
193
  for (_i = 0, _len = allowedFormats.length; _i < _len; _i++) {
123
194
  name = allowedFormats[_i];
124
- if (formats[name].pattern.exec(query)) {
195
+ if (formats[name] && formats[name].pattern.exec(query)) {
125
196
  return formats[name];
126
197
  }
127
198
  }
@@ -152,42 +223,38 @@
152
223
  }
153
224
  ]);
154
225
 
155
- angular.module("angular-smart-search").factory("templateFactory", [
226
+ angular.module("angular-smart-search").service("templateFactory", [
156
227
  "markupStore", function(markupStore) {
157
- return function() {
158
- return " <div> <!-- input section you see initially --> <div class='input-prepend input-append'> <!-- gray display section --> <span class='add-on' style='min-width: 200px;'> <!-- result if found --> <span ng-show='queryState.is(\"successful\")'> <i class='" + (markupStore.successIconClass()) + "'></i> {{result.displayText}} </span> <!-- query states --> <span ng-show='queryState.is(\"changed\")'> <em>{{queryState.query.format.name}} detected</em> </span> <span ng-show='queryState.is(\"pending\")'> <em>searching...</em> </span> <span ng-show='queryState.is(\"unsuccessful\")'> <em>Not found</em> </span> <span ng-show='queryState.is(\"invalid-format\")'> <em>Invalid format</em> </span> <span ng-show='queryState.is(\"error\")'> <em>Error</em> </span> </span> <!-- quick query field --> <input ng-change='outerQueryChanged(quickQuery)' ng-model='quickQuery' queryfield style='width: 100px;' type='text'> <!-- button that triggers detail search overlay --> <button type='button' class='btn' ng-click='show()'> <i class='" + (markupStore.searchIconClass()) + "'></i> </button> </div> <!-- detail search overlay, initially hidden --> <div class='" + (markupStore.overlayClass()) + "' ng-mouseleave='hide()' overlay> <div class='row-fluid'> <div class='span12'> <div class='input-append'> <input detail-queryfield ng-model='detailQuery' type='text'> <button type='button' class='btn' ng-click='search(detailQuery)'> <i class='" + (markupStore.searchIconClass()) + "'></i> </button> </div> </div> </div> <div class='horizontal-space'></div> <div class='row-fluid'> <div class='span12'> <table at-table class='table table-bordered table-hover' fill-last-page pagination='wildPagination'> <thead></thead> <tbody> <tr ng-mouseover='hover(item)'> <td at-implicit attribute='id' class='sortable 50px'></td> <td at-implicit attribute='displayText' class='sortable 280px' title='Result'></td> <td class='50px' title=''> <button type='button' class='btn btn-mini' ng-click='pick(item)'>pick</button> </td> </tr> </tbody> </table> <at-pagination instance='wildPagination' items-per-page='3' list='resultList'></at-pagination> </div> </div> </div> </div> ";
159
- };
160
- }
161
- ]);
162
-
163
- angular.module("angular-smart-search").provider("markupStore", [
164
- function() {
165
- var overlayClass, searchIconClass, successIconClass;
228
+ var detailOverlay, detailOverlayTrigger, inputSection, overlayStyle, resultIcon, searchOverlay, showDetailOverlayAction, successIcon;
166
229
 
167
- successIconClass = "icon-ok";
168
- searchIconClass = "icon-search";
169
- overlayClass = "smart-search-overlay";
170
- this.setSuccessIconClass = function(attr) {
171
- return successIconClass = attr;
230
+ overlayStyle = "style=' display: none; position: absolute; background-color: white; padding: 30px; border: solid; border-width: 1px; border-color: rgb(221, 221, 221); border-radius: 10px; '";
231
+ detailOverlayTrigger = "<i detail-overlay-trigger class='" + (markupStore.infoIconClass()) + "' ng-click='showDetailOverlay()'></i>";
232
+ successIcon = "<i class='" + (markupStore.successIconClass()) + "'></i>";
233
+ showDetailOverlayAction = function(withDetailOverlay) {
234
+ if (withDetailOverlay) {
235
+ return "ng-click='showDetailOverlay()'";
236
+ }
172
237
  };
173
- this.setSearchIconClass = function(attr) {
174
- return searchIconClass = attr;
238
+ resultIcon = function(withDetailOverlay) {
239
+ if (withDetailOverlay) {
240
+ return detailOverlayTrigger;
241
+ } else {
242
+ return successIcon;
243
+ }
175
244
  };
176
- this.setOverlayClass = function(attr) {
177
- return overlayClass = attr;
245
+ inputSection = function(withDetailOverlay) {
246
+ return " <div> <!-- input section you see initially --> <div class='input-prepend input-append'> <!-- gray display section --> <span class='add-on' style='min-width: 200px;'> <!-- result if found --> <span ng-show='queryState.is(\"successful\")' " + (showDetailOverlayAction(withDetailOverlay)) + "> " + (resultIcon(withDetailOverlay)) + " {{result.displayText}} </span> <!-- query states --> <span ng-show='queryState.is(\"changed\")'> <em>{{queryState.query.format.name}} detected</em> </span> <span ng-show='queryState.is(\"pending\")'> <em>searching...</em> </span> <span ng-show='queryState.is(\"unsuccessful\")'> <em>Not found</em> </span> <span ng-show='queryState.is(\"invalid-format\")'> <em>Invalid format</em> </span> <span ng-show='queryState.is(\"error\")'> <em>Error</em> </span> </span> <!-- quick query field --> <input ng-change='outerQueryChanged(quickQuery)' ng-model='quickQuery' quick-query-input style='width: 100px;' type='text'> <!-- button that triggers detail search overlay --> <button type='button' class='btn' ng-click='showSearchOverlay()'> <i class='" + (markupStore.searchIconClass()) + "'></i> </button> </div> " + (detailOverlay()) + " " + (searchOverlay()) + " </div> ";
178
247
  };
179
- return this.$get = function() {
180
- return {
181
- successIconClass: function() {
182
- return successIconClass;
183
- },
184
- searchIconClass: function() {
185
- return searchIconClass;
186
- },
187
- overlayClass: function() {
188
- return overlayClass;
189
- }
190
- };
248
+ searchOverlay = function() {
249
+ return " <search-overlay " + overlayStyle + " class='" + (markupStore.overlayClass()) + "' ng-mouseleave='hideSearchOverlay()'> <div class='row-fluid'> <div class='span12'> <div class='input-append'> <form> <input search-input ng-model='detailQuery' type='text'> <button type='submit' class='btn' ng-click='search(detailQuery)'> <i class='" + (markupStore.searchIconClass()) + "'></i> </button> </form> </div> </div> </div> <div class='horizontal-space'></div> <div class='row-fluid'> <div class='span12'> <table at-table class='table table-bordered table-hover' fill-last-page pagination='wildPagination'> <thead></thead> <tbody> <tr ng-mouseover='hover(item)'> <td at-implicit attribute='id' class='sortable 50px'></td> <td at-implicit attribute='displayText' class='sortable 280px' title='Result'></td> <td class='50px' title=''> <button type='button' class='btn btn-mini' ng-click='pick(item)'>pick</button> </td> </tr> </tbody> </table> <at-pagination instance='wildPagination' items-per-page='3' list='resultList'></at-pagination> </div> </div> </search-overlay> ";
250
+ };
251
+ detailOverlay = function() {
252
+ return " <detail-overlay " + overlayStyle + " class='" + (markupStore.overlayClass()) + "' ng-mouseleave='hideDetailOverlay()'> </detail-overlay> ";
253
+ };
254
+ return {
255
+ getTemplate: function(withDetailOverlay) {
256
+ return inputSection(withDetailOverlay);
257
+ }
191
258
  };
192
259
  }
193
260
  ]);
File without changes
@@ -1,3 +1,3 @@
1
1
  module AngularSmartSearch
2
- VERSION = "0.0.5"
2
+ VERSION = "0.0.6"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: angular-smart-search
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Mueller
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-07-05 00:00:00.000000000 Z
11
+ date: 2013-07-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - '>='
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: listen
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
41
55
  description: angular smart search
42
56
  email:
43
57
  - mueller.samu@gmail.com
@@ -73,4 +87,3 @@ signing_key:
73
87
  specification_version: 4
74
88
  summary: angular smart search
75
89
  test_files: []
76
- has_rdoc: