administrate-field-lat_lng 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +2 -1
- data/administrate-field-lat_lng.gemspec +1 -1
- data/app/views/fields/lat_lng/_map.html.erb +41 -14
- data/lib/administrate/field/lat_lng.rb +22 -7
- data/vendor/assets/javascripts/leaflet-gplaces-autocomplete-0.0.8.js +144 -0
- data/vendor/assets/stylesheets/leaflet-gplaces-autocomplete-0.0.8.css +43 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d18138c50948b551f8f508f321fa2ab1b7176ff4
|
4
|
+
data.tar.gz: e0b5d83b6e52555ce882889e2cf3a461d2cfa78c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4a052e9ad5f71668c3c3fb0fa2586843d08dbc5ec686347e3867c8c1daddfd4e2a0bb007b1c101e33204bcb5d124e82f78f1475a944731170e1dd0ca21e05677
|
7
|
+
data.tar.gz: 2f4c2a81600c7608b402348165c5959ace14b19adca170877cb67a568d56990bea03d9bbbd21d0f5f3ec89ac30f3e73de245113747d1d488a77dd7e25e0761f2
|
data/README.md
CHANGED
@@ -45,6 +45,8 @@ Additional options that are available:
|
|
45
45
|
|
46
46
|
* `initial`: Set to an array like `[53.8003,-1.5519]`. Will cause the center of the map to be this point if the lat/lng have not yet been set (e.g. for new records). Defaults to Leeds, UK (because that's where the author is from).
|
47
47
|
* `zoom`: Set the default zoom level for maps drawn (defaults to 11).
|
48
|
+
* `search`: `true` (default) or `false`. Enable location search. Requires `google_api_key` option too.
|
49
|
+
* `google_api_key`: A [key for the Google Maps JavaScript API](https://developers.google.com/maps/documentation/javascript/get-api-key). Required for location search to work.
|
48
50
|
|
49
51
|
## Usage notes
|
50
52
|
|
@@ -59,4 +61,3 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/fishpe
|
|
59
61
|
## License
|
60
62
|
|
61
63
|
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
62
|
-
|
@@ -2,6 +2,7 @@
|
|
2
2
|
<div id="latlngmap"></div>
|
3
3
|
</div>
|
4
4
|
<% content_for :javascript do %>
|
5
|
+
<%= content_tag(:script, '', src: "https://maps.googleapis.com/maps/api/js?key=#{field.google_api_key}&libraries=places") if field.search? %>
|
5
6
|
<script type="text/javascript">
|
6
7
|
// Attach a leaflet.js map to the div above
|
7
8
|
var map = L.map('latlngmap');
|
@@ -9,7 +10,24 @@
|
|
9
10
|
attribution: 'Map data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors'
|
10
11
|
});
|
11
12
|
map.addLayer(osm);
|
12
|
-
|
13
|
+
|
14
|
+
var createMarker = function(latlng) {
|
15
|
+
var icon = new L.Icon.Default();
|
16
|
+
var options = { icon: icon };
|
17
|
+
marker = L.marker(latlng, options);
|
18
|
+
marker.addTo(map);
|
19
|
+
};
|
20
|
+
|
21
|
+
var setMarker = function (latlng) {
|
22
|
+
if (marker === undefined) {
|
23
|
+
createMarker(latlng);
|
24
|
+
} else {
|
25
|
+
marker.setLatLng(latlng);
|
26
|
+
}
|
27
|
+
$('.latlng-lat').val(latlng.lat);
|
28
|
+
$('.latlng-lng').val(latlng.lng);
|
29
|
+
};
|
30
|
+
|
13
31
|
// Get the centre lat/lng from the field or the initial default if the field
|
14
32
|
// hasn't been set yet
|
15
33
|
var latlng = [];
|
@@ -19,28 +37,37 @@
|
|
19
37
|
latlng = [lat, lng];
|
20
38
|
}
|
21
39
|
map.setView(latlng, <%= field.zoom %>);
|
22
|
-
|
40
|
+
|
23
41
|
// Add a marker if the field has been set already
|
24
42
|
var marker;
|
25
43
|
if (lng !== undefined) {
|
26
|
-
|
27
|
-
var options = { icon: icon };
|
28
|
-
marker = L.marker(latlng, options);
|
29
|
-
marker.addTo(map);
|
44
|
+
createMarker(latlng);
|
30
45
|
}
|
31
46
|
<% if edit %>
|
32
47
|
// In edit mode, move the marker and update the fields when a user clicks
|
33
48
|
// inside the map
|
34
49
|
map.on('click', function (e) {
|
35
|
-
|
36
|
-
marker = L.marker(e.latlng);
|
37
|
-
marker.addTo(map);
|
38
|
-
} else {
|
39
|
-
marker.setLatLng(e.latlng);
|
40
|
-
}
|
41
|
-
$('.latlng-lat').val(e.latlng.lat);
|
42
|
-
$('.latlng-lng').val(e.latlng.lng);
|
50
|
+
setMarker(e.latlng);
|
43
51
|
});
|
44
52
|
<% end %>
|
53
|
+
|
54
|
+
<% if field.search? %>
|
55
|
+
new L.Control.GPlaceAutocomplete({
|
56
|
+
callback: function (place) {
|
57
|
+
map.panTo([
|
58
|
+
place.geometry.location.lat(),
|
59
|
+
place.geometry.location.lng()
|
60
|
+
]);
|
61
|
+
|
62
|
+
<% if edit %>
|
63
|
+
setMarker({
|
64
|
+
lat: place.geometry.location.lat(),
|
65
|
+
lng: place.geometry.location.lng(),
|
66
|
+
});
|
67
|
+
<% end %>
|
68
|
+
},
|
69
|
+
})
|
70
|
+
.addTo(map);
|
71
|
+
<% end %>
|
45
72
|
</script>
|
46
73
|
<% end %>
|
@@ -6,10 +6,16 @@ module Administrate
|
|
6
6
|
module Field
|
7
7
|
class LatLng < Base
|
8
8
|
class Engine < ::Rails::Engine
|
9
|
-
|
9
|
+
if config.respond_to? :assets
|
10
|
+
config.assets.precompile << %w(lat_lng.js lat_lng.css)
|
11
|
+
config.assets.precompile << %w(leaflet-gplaces-autocomplete-0.0.8.css leaflet-gplaces-autocomplete-0.0.8.js)
|
12
|
+
end
|
13
|
+
|
10
14
|
if defined?(Administrate::Engine)
|
11
15
|
Administrate::Engine.add_javascript 'lat_lng.js'
|
12
16
|
Administrate::Engine.add_stylesheet 'lat_lng.css'
|
17
|
+
Administrate::Engine.add_javascript 'leaflet-gplaces-autocomplete-0.0.8.js'
|
18
|
+
Administrate::Engine.add_stylesheet 'leaflet-gplaces-autocomplete-0.0.8.css'
|
13
19
|
end
|
14
20
|
end
|
15
21
|
|
@@ -17,31 +23,40 @@ module Administrate
|
|
17
23
|
def lat?
|
18
24
|
options.fetch(:lat, attribute == :lat)
|
19
25
|
end
|
20
|
-
|
26
|
+
|
21
27
|
# True if the :lng option has been provided, or field is called :lng
|
22
28
|
def lng?
|
23
29
|
options.fetch(:lng, attribute == :lng)
|
24
30
|
end
|
25
|
-
|
31
|
+
|
32
|
+
# Return wether or not search should be enabled (defaults to true)
|
33
|
+
def search?
|
34
|
+
options.fetch(:search, true) && google_api_key.present?
|
35
|
+
end
|
36
|
+
|
37
|
+
# Get Google API Key. How to obtain one: https://developers.google.com/maps/documentation/javascript/get-api-key
|
38
|
+
def google_api_key
|
39
|
+
options.fetch(:google_api_key, nil)
|
40
|
+
end
|
41
|
+
|
26
42
|
# Returns :lat or :lng depending on which type this is
|
27
43
|
def which
|
28
44
|
lat? ? :lat : :lng
|
29
45
|
end
|
30
|
-
|
46
|
+
|
31
47
|
# Returns the initial co-ordinates of blank maps (defaults to Leeds, UK)
|
32
48
|
def initial
|
33
49
|
options.fetch(:initial, [53.8003,-1.5519])
|
34
50
|
end
|
35
|
-
|
51
|
+
|
36
52
|
# Returns the initial zoom level for maps (defaults to 11)
|
37
53
|
def zoom
|
38
54
|
options.fetch(:zoom, 11)
|
39
55
|
end
|
40
|
-
|
56
|
+
|
41
57
|
def to_s
|
42
58
|
data
|
43
59
|
end
|
44
|
-
|
45
60
|
end
|
46
61
|
end
|
47
62
|
end
|
@@ -0,0 +1,144 @@
|
|
1
|
+
(function () {
|
2
|
+
L.GPlaceAutocomplete = {};
|
3
|
+
|
4
|
+
L.Control.GPlaceAutocomplete = L.Control.extend({
|
5
|
+
options: {
|
6
|
+
position: "topright",
|
7
|
+
prepend: true,
|
8
|
+
collapsed_mode: false,
|
9
|
+
autocomplete_options: {}
|
10
|
+
},
|
11
|
+
|
12
|
+
collapsedModeIsExpanded: true,
|
13
|
+
|
14
|
+
autocomplete: null,
|
15
|
+
icon: null,
|
16
|
+
searchBox: null,
|
17
|
+
|
18
|
+
initialize: function (options) {
|
19
|
+
if (options) {
|
20
|
+
L.Util.setOptions(this, options);
|
21
|
+
}
|
22
|
+
if (!this.options.callback) {
|
23
|
+
this.options.callback = this.onLocationComplete;
|
24
|
+
}
|
25
|
+
this._buildContainer();
|
26
|
+
},
|
27
|
+
|
28
|
+
_buildContainer: function () {
|
29
|
+
|
30
|
+
// build structure
|
31
|
+
this.container = L.DomUtil.create("div", "leaflet-gac-container leaflet-bar");
|
32
|
+
var searchWrapper = L.DomUtil.create("div", "leaflet-gac-wrapper");
|
33
|
+
this.searchBox = L.DomUtil.create("input", "leaflet-gac-control");
|
34
|
+
this.autocomplete = new google.maps.places.Autocomplete(this.searchBox, this.options.autocomplete_options);
|
35
|
+
|
36
|
+
// if collapse mode set - create icon and register events
|
37
|
+
if (this.options.collapsed_mode) {
|
38
|
+
this.collapsedModeIsExpanded = false;
|
39
|
+
|
40
|
+
this.icon = L.DomUtil.create("div", "leaflet-gac-search-btn");
|
41
|
+
L.DomEvent
|
42
|
+
.on(this.icon, "click", this._showSearchBar, this);
|
43
|
+
|
44
|
+
this.icon.appendChild(
|
45
|
+
L.DomUtil.create("div", "leaflet-gac-search-icon")
|
46
|
+
);
|
47
|
+
|
48
|
+
searchWrapper.appendChild(
|
49
|
+
this.icon
|
50
|
+
);
|
51
|
+
L.DomUtil.addClass(this.searchBox, "leaflet-gac-hidden");
|
52
|
+
}
|
53
|
+
|
54
|
+
searchWrapper.appendChild(
|
55
|
+
this.searchBox
|
56
|
+
);
|
57
|
+
// create and bind autocomplete
|
58
|
+
this.container.appendChild(
|
59
|
+
searchWrapper
|
60
|
+
);
|
61
|
+
|
62
|
+
},
|
63
|
+
|
64
|
+
//***
|
65
|
+
// Collapse mode callbacks
|
66
|
+
//***
|
67
|
+
|
68
|
+
_showSearchBar: function () {
|
69
|
+
this._toggleSearch(true);
|
70
|
+
},
|
71
|
+
|
72
|
+
_hideSearchBar: function () {
|
73
|
+
// if element is expanded, we need to change expanded flag and call collapse handler
|
74
|
+
if (this.collapsedModeIsExpanded) {
|
75
|
+
this._toggleSearch(false);
|
76
|
+
}
|
77
|
+
},
|
78
|
+
|
79
|
+
_toggleSearch: function (shouldDisplaySearch) {
|
80
|
+
if (shouldDisplaySearch) {
|
81
|
+
L.DomUtil.removeClass(this.searchBox, "leaflet-gac-hidden");
|
82
|
+
L.DomUtil.addClass(this.icon, "leaflet-gac-hidden");
|
83
|
+
this.searchBox.focus();
|
84
|
+
} else {
|
85
|
+
L.DomUtil.addClass(this.searchBox, "leaflet-gac-hidden");
|
86
|
+
L.DomUtil.removeClass(this.icon, "leaflet-gac-hidden");
|
87
|
+
}
|
88
|
+
this.collapsedModeIsExpanded = shouldDisplaySearch;
|
89
|
+
},
|
90
|
+
|
91
|
+
//***
|
92
|
+
// Default success callback
|
93
|
+
//***
|
94
|
+
|
95
|
+
onLocationComplete: function (place, map) {
|
96
|
+
// default callback
|
97
|
+
if (!place.geometry) {
|
98
|
+
alert("Location not found");
|
99
|
+
return;
|
100
|
+
}
|
101
|
+
map.panTo([
|
102
|
+
place.geometry.location.lat(),
|
103
|
+
place.geometry.location.lng()
|
104
|
+
]);
|
105
|
+
|
106
|
+
},
|
107
|
+
|
108
|
+
onAdd: function () {
|
109
|
+
// stop propagation of click events
|
110
|
+
L.DomEvent.addListener(this.container, 'click', L.DomEvent.stop);
|
111
|
+
L.DomEvent.disableClickPropagation(this.container);
|
112
|
+
if (this.options.collapsed_mode) {
|
113
|
+
// if collapse mode - register handler
|
114
|
+
this._map.on('dragstart click', this._hideSearchBar, this);
|
115
|
+
}
|
116
|
+
return this.container;
|
117
|
+
},
|
118
|
+
|
119
|
+
addTo: function (map) {
|
120
|
+
this._map = map;
|
121
|
+
|
122
|
+
var container = this._container = this.onAdd(map),
|
123
|
+
pos = this.options.position,
|
124
|
+
corner = map._controlCorners[pos];
|
125
|
+
|
126
|
+
L.DomUtil.addClass(container, 'leaflet-control');
|
127
|
+
if (this.options.prepend) {
|
128
|
+
corner.insertBefore(container, corner.firstChild);
|
129
|
+
} else {
|
130
|
+
corner.appendChild(container)
|
131
|
+
}
|
132
|
+
|
133
|
+
var callback = this.options.callback;
|
134
|
+
var _this = this;
|
135
|
+
google.maps.event.addListener(this.autocomplete, "place_changed", function () {
|
136
|
+
callback(_this.autocomplete.getPlace(), map);
|
137
|
+
});
|
138
|
+
|
139
|
+
return this;
|
140
|
+
}
|
141
|
+
|
142
|
+
|
143
|
+
});
|
144
|
+
})();
|
@@ -0,0 +1,43 @@
|
|
1
|
+
.leaflet-gac-wrapper {
|
2
|
+
height: 30px;
|
3
|
+
}
|
4
|
+
|
5
|
+
.leaflet-control-container .leaflet-gac-control {
|
6
|
+
width: 300px;
|
7
|
+
height: 30px;
|
8
|
+
padding: 0 7px;
|
9
|
+
border-radius: 5px;
|
10
|
+
border: 1px #d0d0d0 solid;
|
11
|
+
}
|
12
|
+
|
13
|
+
.leaflet-control-container .leaflet-right .leaflet-gac-control {
|
14
|
+
position: absolute;
|
15
|
+
right: 0;
|
16
|
+
transition: width .3s ease .15s;
|
17
|
+
}
|
18
|
+
|
19
|
+
.leaflet-control-container .leaflet-gac-control:focus {
|
20
|
+
outline: none;
|
21
|
+
}
|
22
|
+
|
23
|
+
.leaflet-control-container .leaflet-gac-search-btn {
|
24
|
+
background: #fff;
|
25
|
+
width: 30px;
|
26
|
+
height: 30px;
|
27
|
+
border-radius: 4px;
|
28
|
+
}
|
29
|
+
|
30
|
+
.leaflet-control-container .leaflet-gac-search-btn .leaflet-gac-search-icon {
|
31
|
+
cursor: pointer;
|
32
|
+
width: 100%;
|
33
|
+
height: 100%;
|
34
|
+
background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABOUlEQVQ4T6XTLUgmQRgH8N+Ligd+FOu1ww+wKPhxlwxXxHYnqCAGQZtgMBgU4eWaXLhyCgYxiAYVk6igJotgEaNiNYgGL6kHJwOzsO+yGzw3zszzm5nnP1vyzq+UU9+JUbTiCWdYw13eXmmgCr8wlbPwERPYys6lgVA8jSvM4RQfMIQF1KIfR2kkAdpxiRv04CGzUx9OcI02/EvmE+AH5jGG9YK+bmMQ3TjPApsYQXPcJc+Ywc/Y4I0ssIpxdOCi4ATl2Ivv2M0Ck1jBImZzgOrYoxZ8xG0WqI9Hb4pX2UkhNViKMe5jIC+FMPYVezGu4xhjHb7hUyx6wXDeFRK0C79jlMnYX4SmhZfZiwok7ymHwpBGyPs5RnaPRhzicxopAop+sYAc4Av+BPStQIAbsByffPl/gIrTvQLbJDoR8K3H6QAAAABJRU5ErkJggg==") no-repeat center center;
|
35
|
+
}
|
36
|
+
|
37
|
+
.leaflet-control-container .leaflet-gac-hidden {
|
38
|
+
opacity: 0;
|
39
|
+
width: 0;
|
40
|
+
height: 0;
|
41
|
+
overflow: hidden;
|
42
|
+
transition: width .3s ease .15s;
|
43
|
+
}
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: administrate-field-lat_lng
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rich Daley
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-02
|
11
|
+
date: 2017-03-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: administrate
|
@@ -125,6 +125,8 @@ files:
|
|
125
125
|
- app/views/fields/lat_lng/_show.html.erb
|
126
126
|
- app/views/fields/lat_lng/_var.html.erb
|
127
127
|
- lib/administrate/field/lat_lng.rb
|
128
|
+
- vendor/assets/javascripts/leaflet-gplaces-autocomplete-0.0.8.js
|
129
|
+
- vendor/assets/stylesheets/leaflet-gplaces-autocomplete-0.0.8.css
|
128
130
|
homepage: https://github.com/fishpercolator/administrate-field-lat_lng
|
129
131
|
licenses:
|
130
132
|
- MIT
|