gmaps-autocomplete-rails 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -23,37 +23,108 @@ Packed and ready for the Asset pipeline :)
23
23
 
24
24
  ```javascript
25
25
  $(document).ready(function() {
26
- GmapsAutoComplete.gmaps_init();
27
- GmapsAutoComplete.autocomplete_init();
26
+ GmapsAutoComplete.init();
27
+ GmapsAutoComplete.autoCompleteInit();
28
28
  });
29
29
  ```
30
30
 
31
31
  ## Configuration options
32
32
 
33
- `gmaps_init()` take an option hash, using the following defaults:
33
+ `init()` take an option hash, using the following defaults:
34
34
 
35
35
  ```javascript
36
- defaultOptions = {
37
- mapElem: "#gmaps-canvas",
38
- zoomLevel: 2,
39
- mapType: google.maps.MapTypeId.ROADMAP,
40
- pos: [51.751724, -1.255284],
41
- inputField: '#gmaps-input-address',
42
- errorField: '#gmaps-error',
43
- positionOutputter: this.defaultPositionOutputter
44
- };
36
+ defaultOptions = {
37
+ mapElem: "#gmaps-canvas",
38
+ zoomLevel: 2,
39
+ mapType: google.maps.MapTypeId.ROADMAP,
40
+ pos: [51.751724, -1.255284],
41
+ inputField: '#gmaps-input-address',
42
+ errorField: '#gmaps-error',
43
+ positionOutputter: this.defaultPositionOutputter,
44
+ updateUI : this.defaultUpdateUI,
45
+ updateMap : this.defaultUpdateMap
46
+ };
45
47
  ```
46
48
 
47
- `autocomplete_init` also takes an option hash, but currently only [region](https://developers.google.com/maps/documentation/geocoding/#RegionCodes) is used.
49
+ `autoCompleteInit` also takes an option hash, but currently only [region](https://developers.google.com/maps/documentation/geocoding/#RegionCodes) is used.
48
50
 
49
51
  ```javascript
50
- autocomplete_init({region: 'ES'});
52
+ autoCompleteInit({region: 'USA'});
53
+ ```
54
+
55
+ # Examples
56
+
57
+ See `spec/index.html` for an example page using this "plugin". Note that if you set `mapElem`to null or leave out that element on the page, the autocomplete will function without attempting to update the map :)
58
+
59
+ ## Customization
60
+
61
+ Some of the prime candidate functions for customization are:
62
+
63
+ * updateUi
64
+ * updateMap
65
+
66
+ Here the default simple `updateUI` implementation:
67
+
68
+ ```javascript
69
+ updateUi: function( address, latLng ) {
70
+ $(this.inputField).autocomplete("close");
71
+ $(this.inputField).val(address);
72
+
73
+ this.positionOutputter(latLng);
74
+ }
75
+ ```
76
+
77
+ Let's enrich the autocomplete fields with a jobs count for "the area" for each address.
78
+
79
+ ```javascript
80
+ updateUi: function( address, latLng ) {
81
+ $(this.inputField).autocomplete("close");
82
+
83
+ var jobsCount = $.ajax(url: 'jobs/search?address=' + address + '&type=count');
84
+
85
+ $(this.inputField).val(address + ' (' + jobsCount + ' jobs)');
86
+ }
87
+ ```
88
+
89
+ ## Customize messages
90
+
91
+ For now, directly define your own implementation (override) the following functions directly on GmapsAutoComplete
92
+
93
+ * geocodeErrorMsg: function()
94
+ * invalidAddressMsg: function(value)
95
+ * noAddressFoundMsg: function()
96
+
97
+ Example:
98
+
99
+ ```javascript
100
+
101
+ GmapsAutoComplete.geocodeErrorMsg = function() {
102
+ "Geocode error!"
103
+ }
104
+ ```
105
+
106
+ ## Formtastic example
107
+
108
+ For [formtastic](https://github.com/justinfrench/formtastic) something like:
109
+
110
+ ```ruby
111
+ = semantic_form_for @search do |f|
112
+ = f.input :address, placeholder: 'find address'
113
+ %span#address_error
114
+
115
+ ```javascript
116
+ $(document).ready(function() {
117
+ GmapsAutoComplete.init({inputField: 'form#search #address', errorField: 'form#search #address_error'});
118
+ GmapsAutoComplete.autoCompleteInit({region: 'DK'});
119
+ });
51
120
  ```
52
121
 
53
122
  ## TODO
54
123
 
55
124
  * better Javascript encapsulation
56
- * translation to Coffeescript and use Coffee classes :)
125
+ * translation to Coffeescript using Coffee classes :)
126
+
127
+ Please help out with suggestions and improvements etc!
57
128
 
58
129
  ## Contributing to gmaps-autocomplete-rails
59
130
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0
1
+ 0.1.1
@@ -0,0 +1,86 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "gmaps-autocomplete-rails"
8
+ s.version = "0.1.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Kristian Mandrup"]
12
+ s.date = "2012-09-07"
13
+ s.description = "Easily add autocomplete geo-functionality to your Rails app :)"
14
+ s.email = "kmandrup@gmail.com"
15
+ s.extra_rdoc_files = [
16
+ "LICENSE.txt",
17
+ "README.md"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".rspec",
22
+ "Gemfile",
23
+ "Gemfile.lock",
24
+ "LICENSE.txt",
25
+ "README.md",
26
+ "Rakefile",
27
+ "VERSION",
28
+ "gmaps-autocomplete-rails.gemspec",
29
+ "lib/gmaps-autocomplete-rails.rb",
30
+ "lib/gmaps-autocomplete/view_helper.rb",
31
+ "spec/index.html",
32
+ "spec/init.js",
33
+ "spec/jquery-ui/images/ui-bg_flat_0_aaaaaa_40x100.png",
34
+ "spec/jquery-ui/images/ui-bg_glass_55_fbf9ee_1x400.png",
35
+ "spec/jquery-ui/images/ui-bg_glass_65_ffffff_1x400.png",
36
+ "spec/jquery-ui/images/ui-bg_glass_75_dadada_1x400.png",
37
+ "spec/jquery-ui/images/ui-bg_glass_75_e6e6e6_1x400.png",
38
+ "spec/jquery-ui/images/ui-bg_glass_75_ffffff_1x400.png",
39
+ "spec/jquery-ui/images/ui-bg_highlight-soft_75_cccccc_1x100.png",
40
+ "spec/jquery-ui/images/ui-bg_inset-soft_95_fef1ec_1x100.png",
41
+ "spec/jquery-ui/images/ui-icons_222222_256x240.png",
42
+ "spec/jquery-ui/images/ui-icons_2e83ff_256x240.png",
43
+ "spec/jquery-ui/images/ui-icons_454545_256x240.png",
44
+ "spec/jquery-ui/images/ui-icons_888888_256x240.png",
45
+ "spec/jquery-ui/images/ui-icons_cd0a0a_256x240.png",
46
+ "spec/jquery-ui/images/ui-icons_f6cf3b_256x240.png",
47
+ "spec/jquery-ui/jquery-ui-1.8.16.custom.css",
48
+ "spec/jquery-ui/jquery.ui.1.8.16.ie.css",
49
+ "spec/main.css",
50
+ "spec/spec_helper.rb",
51
+ "vendor/assets/javascripts/gmaps-autocomplete.js"
52
+ ]
53
+ s.homepage = "http://github.com/kristianmandrup/gmaps-autocomplete-rails"
54
+ s.licenses = ["MIT"]
55
+ s.require_paths = ["lib"]
56
+ s.rubygems_version = "1.8.24"
57
+ s.summary = "Google Maps v3 search with jQuery UI Autocomplete, ready for use with Rails asset pipeline"
58
+
59
+ if s.respond_to? :specification_version then
60
+ s.specification_version = 3
61
+
62
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
63
+ s.add_runtime_dependency(%q<rails>, [">= 3.0.0"])
64
+ s.add_development_dependency(%q<rspec>, [">= 2.8.0"])
65
+ s.add_development_dependency(%q<rdoc>, [">= 3.12"])
66
+ s.add_development_dependency(%q<bundler>, [">= 1.0.0"])
67
+ s.add_development_dependency(%q<jeweler>, ["~> 1.8.4"])
68
+ s.add_development_dependency(%q<simplecov>, [">= 0.5"])
69
+ else
70
+ s.add_dependency(%q<rails>, [">= 3.0.0"])
71
+ s.add_dependency(%q<rspec>, [">= 2.8.0"])
72
+ s.add_dependency(%q<rdoc>, [">= 3.12"])
73
+ s.add_dependency(%q<bundler>, [">= 1.0.0"])
74
+ s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
75
+ s.add_dependency(%q<simplecov>, [">= 0.5"])
76
+ end
77
+ else
78
+ s.add_dependency(%q<rails>, [">= 3.0.0"])
79
+ s.add_dependency(%q<rspec>, [">= 2.8.0"])
80
+ s.add_dependency(%q<rdoc>, [">= 3.12"])
81
+ s.add_dependency(%q<bundler>, [">= 1.0.0"])
82
+ s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
83
+ s.add_dependency(%q<simplecov>, [">= 0.5"])
84
+ end
85
+ end
86
+
@@ -1,4 +1,4 @@
1
1
  $(document).ready(function() {
2
- GmapsAutoComplete.gmaps_init();
3
- GmapsAutoComplete.autocomplete_init();
2
+ GmapsAutoComplete.init();
3
+ GmapsAutoComplete.autoCompleteInit();
4
4
  });
@@ -5,6 +5,9 @@ var GmapsAutoComplete = {
5
5
  inputField: null,
6
6
  errorField: null,
7
7
  positionOutputter: null,
8
+ updateUI: null,
9
+ updateMap: null,
10
+ region: null,
8
11
 
9
12
  // initialise the google maps objects, and add listeners
10
13
  mapElem: document.getElementById("gmaps-canvas"),
@@ -15,7 +18,7 @@ var GmapsAutoComplete = {
15
18
  errorField: '#gmaps-error',
16
19
  positionOutputter: this.defaultPositionOutputter,
17
20
 
18
- gmaps_init: function(opts){
21
+ init: function(opts){
19
22
  opts = opts || {};
20
23
 
21
24
  defaultOptions = {
@@ -25,7 +28,9 @@ var GmapsAutoComplete = {
25
28
  pos: [51.751724, -1.255284],
26
29
  inputField: '#gmaps-input-address',
27
30
  errorField: '#gmaps-error',
28
- positionOutputter: this.defaultPositionOutputter
31
+ positionOutputter: this.defaultPositionOutputter,
32
+ updateUI : this.defaultUpdateUI,
33
+ updateMap : this.defaultUpdateMap
29
34
  };
30
35
 
31
36
  $.extend(opts, defaultOptions);
@@ -47,6 +52,8 @@ var GmapsAutoComplete = {
47
52
  this.errorField = opts['#gmaps-error'];
48
53
 
49
54
  this.positionOutputter = opts['positionOutputter'];
55
+ this.updateUI = opts['updateUI'];
56
+ this.updateMap = opts['updateMap'];
50
57
 
51
58
  // center of the universe
52
59
  var latlng = new google.maps.LatLng(lat, lng);
@@ -66,46 +73,52 @@ var GmapsAutoComplete = {
66
73
  self.showError("Map element " + opts['mapElem'] + " could not be resolved!");
67
74
  }
68
75
 
69
- if (mapElem) {
70
- // create our map object
71
- this.map = new google.maps.Map(mapElem, options);
72
-
73
- if (this.map) {
74
- // the marker shows us the position of the latest address
75
- this.marker = new google.maps.Marker({
76
- map: this.map,
77
- draggable: true
78
- });
79
-
80
- marker = this.marker;
81
-
82
- // event triggered when marker is dragged and dropped
83
- google.maps.event.addListener(this.marker, 'dragend', function() {
84
- self.geocode_lookup( 'latLng', marker.getPosition() );
85
- });
86
-
87
- // event triggered when map is clicked
88
- google.maps.event.addListener(this.map, 'click', function(event) {
89
- marker.setPosition(event.latLng)
90
- self.geocode_lookup( 'latLng', event.latLng );
91
- });
92
- }
93
- }
76
+ if (!mapElem) { return }
77
+
78
+ // create our map object
79
+ this.map = new google.maps.Map(mapElem, options);
80
+
81
+ if (!this.map) { return }
82
+
83
+ // the marker shows us the position of the latest address
84
+ this.marker = new google.maps.Marker({
85
+ map: this.map,
86
+ draggable: true
87
+ });
88
+
89
+ self.addMapListeners(this.marker, this.map);
90
+ },
91
+
92
+ addMapListeners: function(marker, map) {
93
+ self = this;
94
+ // event triggered when marker is dragged and dropped
95
+ google.maps.event.addListener(marker, 'dragend', function() {
96
+ self.geocodeLookup( 'latLng', marker.getPosition() );
97
+ });
98
+
99
+ // event triggered when map is clicked
100
+ google.maps.event.addListener(map, 'click', function(event) {
101
+ marker.setPosition(event.latLng)
102
+ self.geocodeLookup( 'latLng', event.latLng );
103
+ });
94
104
  },
95
105
 
96
106
  // move the marker to a new position, and center the map on it
97
- update_map: function( geometry ) {
98
- if (this.map) {
99
- this.map.fitBounds( geometry.viewport )
107
+ defaultUpdateMap: function( geometry ) {
108
+ var map = this.map;
109
+ var marker = this.marker;
110
+
111
+ if (map) {
112
+ map.fitBounds( geometry.viewport )
100
113
  }
101
114
 
102
- if (this.marker) {
103
- this.marker.setPosition( geometry.location )
115
+ if (marker) {
116
+ marker.setPosition( geometry.location )
104
117
  }
105
118
  },
106
119
 
107
120
  // fill in the UI elements with new position data
108
- update_ui: function( address, latLng ) {
121
+ defaultUpdateUI: function( address, latLng ) {
109
122
  $(this.inputField).autocomplete("close");
110
123
  $(this.inputField).val(address);
111
124
 
@@ -125,7 +138,7 @@ var GmapsAutoComplete = {
125
138
  // value: search query
126
139
  //
127
140
  // update: should we update the map (center map and position marker)?
128
- geocode_lookup: function( type, value, update ) {
141
+ geocodeLookup: function( type, value, update ) {
129
142
  // default value: update = false
130
143
  update = typeof update !== 'undefined' ? update : false;
131
144
 
@@ -133,101 +146,127 @@ var GmapsAutoComplete = {
133
146
  request[type] = value;
134
147
  var self = this;
135
148
 
136
- geocoder.geocode({address: request.term, region: 'DK'}, function(results, status) {
137
- $(self.errorField).html('');
138
- if (status == google.maps.GeocoderStatus.OK) {
139
- // Google geocoding has succeeded!
140
- if (results[0]) {
141
- // Always update the UI elements with new location data
142
- self.update_ui( results[0].formatted_address,
143
- results[0].geometry.location )
144
-
145
- // Only update the map (position marker and center map) if requested
146
- if( update ) { update_map( results[0].geometry ) }
147
- } else {
148
- // Geocoder status ok but no results!?
149
- self.showError("Sorry, something went wrong. Try again!");
150
- }
151
- } else {
152
- // Google Geocoding has failed. Two common reasons:
153
- // * Address not recognised (e.g. search for 'zxxzcxczxcx')
154
- // * Location doesn't map to address (e.g. click in middle of Atlantic)
155
-
156
- if( type == 'address' ) {
157
- // User has typed in an address which we can't geocode to a location
158
- self.showError("Sorry! We couldn't find " + value + ". Try a different search term, or click the map." );
159
- } else {
160
- // User has clicked or dragged marker to somewhere that Google can't do a reverse lookup for
161
- // In this case we display a warning, clear the address box, but fill in LatLng
162
- self.showError("Woah... that's pretty remote! You're going to have to manually enter a place name." );
163
- self.update_ui('', value)
164
- }
165
- };
166
- });
149
+ geocoder.geocode(request, performGeocode);
150
+ },
151
+
152
+ performGeocode: function(results, status) {
153
+ $(self.errorField).html('');
154
+ if (status == google.maps.GeocoderStatus.OK) {
155
+ self.geocodeSuccess(results);
156
+ } else {
157
+ self.geocodeFailure(type, value);
158
+ };
159
+ },
160
+
161
+ geocodeSuccess: function(results) {
162
+ // Google geocoding has succeeded!
163
+ if (results[0]) {
164
+ // Always update the UI elements with new location data
165
+ this.updateUI( results[0].formatted_address,
166
+ results[0].geometry.location )
167
+
168
+ // Only update the map (position marker and center map) if requested
169
+ if( update ) { this.updateMap( results[0].geometry ) }
170
+ } else {
171
+ // Geocoder status ok but no results!?
172
+ this.showError( this.geocodeErrorMsg() );
173
+ }
174
+ },
175
+
176
+ geocodeFailure: function(type, value) {
177
+ // Google Geocoding has failed. Two common reasons:
178
+ // * Address not recognised (e.g. search for 'zxxzcxczxcx')
179
+ // * Location doesn't map to address (e.g. click in middle of Atlantic)
180
+ if( type == 'address' ) {
181
+ // User has typed in an address which we can't geocode to a location
182
+ this.showError( this.invalidAddressMsg(value) );
183
+ } else {
184
+ // User has clicked or dragged marker to somewhere that Google can't do a reverse lookup for
185
+ // In this case we display a warning, clear the address box, but fill in LatLng
186
+ this.showError( this.noAddressFoundMsg() );
187
+ this.updateUI('', value)
188
+ }
189
+ },
190
+
191
+ geocodeErrorMsg: function() {
192
+ "Sorry, something went wrong. Try again!"
193
+ },
194
+
195
+ invalidAddressMsg: function(value) {
196
+ "Sorry! We couldn't find " + value + ". Try a different search term, or click the map."
197
+ },
198
+
199
+ noAddressFoundMsg: function() {
200
+ "Woah... that's pretty remote! You're going to have to manually enter a place name."
167
201
  },
168
202
 
169
203
  showError: function(msg) {
170
- $(self.errorField).html(msg);
171
- $(self.errorField).show();
204
+ $(this.errorField).html(msg);
205
+ $(this.errorField).show();
172
206
 
173
207
  setTimeout(function(){
174
- $(self.errorField).hide();
208
+ $(this.errorField).hide();
175
209
  }, 1000);
176
210
  },
177
211
 
178
212
  // initialise the jqueryUI autocomplete element
179
- autocomplete_init: function (opts) {
180
- var self = this;
213
+ autoCompleteInit: function (opts) {
181
214
  opts = opts || {};
182
- var region = opts['region'] || 'DK';
183
-
184
- $(self.inputField).autocomplete({
215
+ this.region = opts['region'] || 'DK';
185
216
 
217
+ $(this.inputField).autocomplete({
186
218
  // source is the list of input options shown in the autocomplete dropdown.
187
219
  // see documentation: http://jqueryui.com/demos/autocomplete/
188
- source: function(request,response) {
189
-
190
- // https://developers.google.com/maps/documentation/geocoding/#RegionCodes
191
- console.log('region', region);
192
- var region_postfix = ''
193
- if (region) {
194
- region_postfix = ', ' + region
195
- }
196
-
197
- geocode_opts = {'address': request.term + region_postfix }
198
-
199
- // the geocode method takes an address or LatLng to search for
200
- // and a callback function which should process the results into
201
- // a format accepted by jqueryUI autocomplete
202
- geocoder.geocode(geocode_opts, function(results, status) {
203
- response($.map(results, function(item) {
204
- return {
205
- label: item.formatted_address, // appears in dropdown box
206
- value: item.formatted_address, // inserted into input element when selected
207
- geocode: item // all geocode data: used in select callback event
208
- }
209
- }));
210
- })
211
- },
212
-
220
+ source: this.autoCompleteSource,
213
221
  // event triggered when drop-down option selected
214
- select: function(event,ui){
215
- self.update_ui( ui.item.value, ui.item.geocode.geometry.location )
216
- self.update_map( ui.item.geocode.geometry )
217
- }
222
+ select: this.autoCompleteSelect
218
223
  });
219
224
 
220
225
  // triggered when user presses a key in the address box
221
- $(self.inputField).bind('keydown', function(event) {
222
- if(event.keyCode == 13) {
223
- geocode_lookup( 'address', $(self.inputField).val(), true );
224
-
225
- // ensures dropdown disappears when enter is pressed
226
- $(self.inputField).autocomplete("disable")
227
- } else {
228
- // re-enable if previously disabled above
229
- $(self.inputField).autocomplete("enable")
230
- }
231
- });
232
- } // autocomplete_init
226
+ $(self.inputField).bind('keydown', this.keyDownHandler);
227
+ }, // autocomplete_init
228
+
229
+ keyDownHandler: function(event) {
230
+ if(event.keyCode == 13) {
231
+ this.geocodeLookup( 'address', $(self.inputField).val(), true );
232
+
233
+ // ensures dropdown disappears when enter is pressed
234
+ $(this.inputField).autocomplete("disable")
235
+ } else {
236
+ // re-enable if previously disabled above
237
+ $(this.inputField).autocomplete("enable")
238
+ }
239
+ },
240
+
241
+ // self grants access to caller scope
242
+ autoCompleteSelect: function(event,ui){
243
+ self.updateUI( ui.item.value, ui.item.geocode.geometry.location )
244
+ self.updateMap( ui.item.geocode.geometry )
245
+ },
246
+
247
+ // self grants access to caller scope
248
+ autoCompleteSource: function(request,response) {
249
+ // https://developers.google.com/maps/documentation/geocoding/#RegionCodes
250
+ var region_postfix = ''
251
+ var region = self.region;
252
+
253
+ if (region) {
254
+ region_postfix = ', ' + region
255
+ }
256
+
257
+ geocode_opts = {'address': request.term + region_postfix }
258
+
259
+ // the geocode method takes an address or LatLng to search for
260
+ // and a callback function which should process the results into
261
+ // a format accepted by jqueryUI autocomplete
262
+ geocoder.geocode(geocode_opts, function(results, status) {
263
+ response($.map(results, function(item) {
264
+ return {
265
+ label: item.formatted_address, // appears in dropdown box
266
+ value: item.formatted_address, // inserted into input element when selected
267
+ geocode: item // all geocode data: used in select callback event
268
+ }
269
+ }));
270
+ })
271
+ }
233
272
  }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gmaps-autocomplete-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-09-06 00:00:00.000000000 Z
12
+ date: 2012-09-07 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -123,6 +123,7 @@ files:
123
123
  - README.md
124
124
  - Rakefile
125
125
  - VERSION
126
+ - gmaps-autocomplete-rails.gemspec
126
127
  - lib/gmaps-autocomplete-rails.rb
127
128
  - lib/gmaps-autocomplete/view_helper.rb
128
129
  - spec/index.html
@@ -161,7 +162,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
161
162
  version: '0'
162
163
  segments:
163
164
  - 0
164
- hash: 2031419109795997149
165
+ hash: -4192616330667044491
165
166
  required_rubygems_version: !ruby/object:Gem::Requirement
166
167
  none: false
167
168
  requirements: