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