]> git.openstreetmap.org Git - rails.git/blob - app/assets/javascripts/index/notes.js.erb
Merge branch 'master' into notes
[rails.git] / app / assets / javascripts / index / notes.js.erb
1 //= require templates/notes/show
2 //= require templates/notes/new
3
4 $(document).ready(function () {
5   var params = OSM.mapParams();
6
7   var noteIcons = {
8     "new": L.icon({
9       iconUrl: "<%= image_path 'new_note_marker.png' %>",
10       iconSize: [22, 22],
11       iconAnchor: [11, 11]
12     }),
13     "open": L.icon({
14       iconUrl: "<%= image_path 'open_note_marker.png' %>",
15       iconSize: [22, 22],
16       iconAnchor: [11, 11]
17     }),
18     "closed": L.icon({
19       iconUrl: "<%= image_path 'closed_note_marker.png' %>",
20       iconSize: [22, 22],
21       iconAnchor: [11, 11]
22     })
23   };
24
25   var noteLayer = new L.LayerGroup();
26   var notes = {};
27   var newNote;
28
29   map.on("layeradd", function (e) {
30     if (e.layer == noteLayer) {
31       loadNotes();
32       map.on("moveend", loadNotes);
33     }
34   });
35
36   map.on("layerremove", function (e) {
37     if (e.layer == noteLayer) {
38       map.off("moveend", loadNotes);
39       noteLayer.clearLayers();
40       notes = {};
41     }
42   });
43
44   map.on("popupclose", function (e) {
45     if (newNote && e.popup == newNote._popup) {
46       $(newNote).oneTime(10, "removenote", function () {
47         map.removeLayer(newNote);
48         newNote = null;
49       });
50     }
51   });
52
53   if (OSM.STATUS != 'api_offline' && OSM.STATUS != 'database_offline') {
54     map.layersControl.addOverlay(noteLayer, I18n.t("browse.start_rjs.notes_layer_name"));
55
56     if (params.notes) map.addLayer(noteLayer);
57
58     if (params.note) {
59       $.ajax({
60         url: "/api/" + OSM.API_VERSION + "/notes/" + params.note + ".json",
61         success: function (feature) {
62           var marker = updateMarker(notes[feature.properties.id], feature);
63
64           notes[feature.properties.id] = marker;
65
66           map.addLayer(noteLayer);
67           marker.openPopup();
68         }
69       });
70     }
71   }
72
73   function updateMarker(marker, feature) {
74     var icon = noteIcons[feature.properties.status];
75     var popupContent = createPopupContent(marker, feature.properties);
76
77     if (marker)
78     {
79       marker.setIcon(noteIcons[feature.properties.status]);
80       marker._popup.setContent(popupContent);
81     }
82     else
83     {
84       marker = L.marker(feature.geometry.coordinates.reverse(), {
85         icon: icon,
86         opacity: 0.7
87       });
88
89       marker.addTo(noteLayer).bindPopup(popupContent, popupOptions());
90     }
91
92     return marker;
93   }
94
95   var noteLoader;
96
97   function loadNotes() {
98     var bounds = map.getBounds();
99     var size = bounds.getSize();
100
101     if (size <= OSM.MAX_NOTE_REQUEST_AREA) {
102       var url = "/api/" + OSM.API_VERSION + "/notes.json?bbox=" + bounds.toBBOX();
103
104       if (noteLoader) noteLoader.abort();
105
106       noteLoader = $.ajax({
107         url: url,
108         success: function (json) {
109           var oldNotes = notes;
110
111           notes = {};
112
113           json.features.forEach(function (feature) {
114             var marker = oldNotes[feature.properties.id];
115
116             delete oldNotes[feature.properties.id];
117
118             notes[feature.properties.id] = updateMarker(marker, feature);
119           });
120
121           for (id in oldNotes) {
122             noteLayer.removeLayer(oldNotes[id]);
123           }
124
125           noteLoader = null;
126         }
127       });
128     }
129   };
130
131   function popupOptions() {
132     var mapSize = map.getSize();
133
134     return {
135       minWidth: 320,
136       maxWidth: mapSize.y * 1 / 3,
137       maxHeight: mapSize.y * 2 / 3,
138       offset: new L.Point(0, -3),
139       autoPanPadding: new L.Point(60, 40)
140     };
141   }
142
143   function createPopupContent(marker, properties) {
144     var content = $(JST["templates/notes/show"]({ note: properties }));
145
146     content.find("textarea").on("input", function (e) {
147       var form = e.target.form;
148
149       if ($(e.target).val() == "") {
150         $(form.close).val(I18n.t("javascripts.notes.show.resolve"));
151         $(form.comment).prop("disabled", true);
152       } else {
153         $(form.close).val(I18n.t("javascripts.notes.show.comment_and_resolve"));
154         $(form.comment).prop("disabled", false);
155       }
156     });
157
158     content.find("input[type=submit]").on("click", function (e) {
159       e.preventDefault();
160       updateNote(marker, e.target.form, $(e.target).data("url"));
161     });
162
163     return content[0];
164   }
165
166   function createNote(marker, form, url) {
167     var location = marker.getLatLng();
168
169     $(form).find("input[type=submit]").prop("disabled", true);
170
171     $.ajax({
172       url: url,
173       type: "POST",
174       oauth: true,
175       data: {
176         lat: location.lat,
177         lon: location.lng,
178         text: $(form.text).val()
179       },
180       success: function (feature) {
181         notes[feature.properties.id] = updateMarker(marker, feature);
182         newNote = null;
183
184         $("#createnoteanchor").removeClass("disabled").addClass("geolink");
185       }
186     });
187   }
188
189   function updateNote(marker, form, url) {
190     $(form).find("input[type=submit]").prop("disabled", true);
191
192     $.ajax({
193       url: url,
194       type: "POST",
195       oauth: true,
196       data: {
197         text: $(form.text).val()
198       },
199       success: function (feature) {
200         var popupContent = createPopupContent(marker, feature.properties);
201
202         marker.setIcon(noteIcons[feature.properties.status]);
203         marker._popup.setContent(popupContent);
204       }
205     });
206   }
207
208   $("#createnoteanchor").click(function (e) {
209     e.preventDefault();
210
211     if ($(e.target).hasClass("disabled")) return;
212
213     $(e.target).removeClass("geolink").addClass("disabled");
214
215     map.addLayer(noteLayer);
216
217     var mapSize = map.getSize();
218     var markerPosition;
219
220     if (mapSize.y > 800)
221     {
222       markerPosition = [mapSize.x / 2, mapSize.y / 2];
223     }
224     else if (mapSize.y > 400)
225     {
226       markerPosition = [mapSize.x / 2, 400];
227     }
228     else
229     {
230       markerPosition = [mapSize.x / 2, mapSize.y];
231     }
232
233     newNote = L.marker(map.containerPointToLatLng(markerPosition), {
234       icon: noteIcons["new"],
235       opacity: 0.7,
236       draggable: true
237     });
238
239     var popupContent = $(JST["templates/notes/new"]({ create_url: $(e.target).attr("href") }));
240
241     popupContent.find("textarea").on("input", function (e) {
242       var form = e.target.form;
243
244       if ($(e.target).val() == "") {
245         $(form.add).prop("disabled", true);
246       } else {
247         $(form.add).prop("disabled", false);
248       }
249     });
250
251     popupContent.find("input[type=submit]").on("click", function (e) {
252       e.preventDefault();
253       createNote(newNote, e.target.form, $(e.target).data("url"));
254     });
255
256     newNote.addTo(noteLayer).bindPopup(popupContent[0], popupOptions()).openPopup();
257
258     newNote.on("remove", function (e) {
259       $("#createnoteanchor").removeClass("disabled").addClass("geolink");
260     });
261
262     newNote.on("dragstart", function (e) {
263       $(newNote).stopTime("removenote");
264     });
265
266     newNote.on("dragend", function (e) {
267       e.target.openPopup();
268     });
269   });
270 });