]> git.openstreetmap.org Git - rails.git/blob - app/assets/javascripts/index/notes.js.erb
ac73e13782945089c7933f60dc71ec635459e861
[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       noteLayer = new L.LayerGroup(),
7       notes = {},
8       newNote;
9
10   var noteIcons = {
11     "new": L.icon({
12       iconUrl: "<%= image_path 'new_note_marker.png' %>",
13       iconSize: [25, 40],
14       iconAnchor: [12, 40]
15     }),
16     "open": L.icon({
17       iconUrl: "<%= image_path 'open_note_marker.png' %>",
18       iconSize: [25, 40],
19       iconAnchor: [12, 40]
20     }),
21     "closed": L.icon({
22       iconUrl: "<%= image_path 'closed_note_marker.png' %>",
23       iconSize: [25, 40],
24       iconAnchor: [12, 40]
25     })
26   };
27
28   layers.push({
29     layer: noteLayer,
30     layerCode: "N"
31   });
32
33   map.noteLayer = noteLayer;
34
35   map.on("layeradd", function (e) {
36     if (e.layer == noteLayer) {
37       loadNotes();
38       map.on("moveend", loadNotes);
39     }
40   }).on("layerremove", function (e) {
41     if (e.layer == noteLayer) {
42       map.off("moveend", loadNotes);
43       noteLayer.clearLayers();
44       notes = {};
45     }
46   }).on("popupclose", function (e) {
47     if (newNote && e.popup == newNote._popup) {
48       $(newNote).oneTime(10, "removenote", function () {
49         map.removeLayer(newNote);
50         newNote = null;
51       });
52     }
53   }).on("popupopen", function (e) {
54     if (!('ontouchstart' in document.documentElement)) {
55       $(e.popup._container).find(".comment").focus();
56     }
57   });
58
59   if (OSM.STATUS != 'api_offline' && OSM.STATUS != 'database_offline') {
60     if (params.layers) setMapLayers(params.layers);
61     if (params.notes) map.addLayer(noteLayer);
62     if (params.note) {
63       $.ajax({
64         url: "/api/" + OSM.API_VERSION + "/notes/" + params.note + ".json",
65         success: function (feature) {
66           var marker = updateMarker(notes[feature.properties.id], feature);
67           notes[feature.properties.id] = marker;
68           map.addLayer(noteLayer);
69           marker.openPopup();
70         }
71       });
72     }
73   }
74
75   function updateMarker(marker, feature) {
76     if (marker) {
77       marker.setIcon(noteIcons[feature.properties.status]);
78       marker.setPopupContent(createPopupContent(
79         marker, feature.properties,
80         $(marker._popup._content).find("textarea").val()
81       ));
82     } else {
83       marker = L.marker(feature.geometry.coordinates.reverse(), {
84         icon: noteIcons[feature.properties.status],
85         opacity: 0.9
86       });
87       marker.addTo(noteLayer).bindPopup(
88         createPopupContent(marker, feature.properties),
89         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.toBBoxString();
103
104       if (noteLoader) noteLoader.abort();
105
106       noteLoader = $.ajax({
107         url: url,
108         success: success
109       });
110     }
111
112     function success(json) {
113       var oldNotes = notes;
114       notes = {};
115       json.features.forEach(updateMarkers);
116
117       function updateMarkers(feature) {
118         var marker = oldNotes[feature.properties.id];
119         delete oldNotes[feature.properties.id];
120         notes[feature.properties.id] = updateMarker(marker, feature);
121       }
122
123       for (id in oldNotes) {
124         noteLayer.removeLayer(oldNotes[id]);
125       }
126
127       noteLoader = null;
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, -40),
139       autoPanPadding: new L.Point(60, 40)
140     };
141   }
142
143   function createPopupContent(marker, properties, comment) {
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       var data = $(e.target).data();
161       updateNote(marker, e.target.form, data.method, data.url);
162     });
163
164     if (comment) {
165       content.find("textarea").val(comment).trigger("input");
166     }
167
168     return content[0];
169   }
170
171   function createNote(marker, form, url) {
172     var location = marker.getLatLng();
173
174     marker.options.draggable = false;
175     marker.dragging.disable();
176
177     $(form).find("input[type=submit]").prop("disabled", true);
178
179     $.ajax({
180       url: url,
181       type: "POST",
182       oauth: true,
183       data: {
184         lat: location.lat,
185         lon: location.lng,
186         text: $(form.text).val()
187       },
188       success: noteCreated
189     });
190
191     function noteCreated(feature) {
192       $(marker._popup._content).find("textarea").val("");
193
194       notes[feature.properties.id] = updateMarker(marker, feature);
195       newNote = null;
196
197       $("#createnoteanchor").removeClass("disabled").addClass("geolink");
198     }
199   }
200
201   function updateNote(marker, form, method, url) {
202     $(form).find("input[type=submit]").prop("disabled", true);
203
204     $.ajax({
205       url: url,
206       type: method,
207       oauth: true,
208       data: {
209         text: $(form.text).val()
210       },
211       success: function (feature) {
212         if (feature.properties.status == "hidden") {
213           noteLayer.removeLayer(marker);
214
215           delete notes[feature.properties.id];
216         } else {
217           var popupContent = createPopupContent(marker, feature.properties);
218
219           marker.setIcon(noteIcons[feature.properties.status]);
220           marker.setPopupContent(popupContent);
221         }
222       }
223     });
224   }
225
226   $(".leaflet-control-attribution").on("click", "#createnoteanchor", function (e) {
227     e.preventDefault();
228
229     if ($(e.target).hasClass("disabled")) return;
230
231     $(e.target).removeClass("geolink").addClass("disabled");
232
233     map.addLayer(noteLayer);
234
235     var mapSize = map.getSize();
236     var markerPosition;
237
238     if (mapSize.y > 800) {
239       markerPosition = [mapSize.x / 2, mapSize.y / 2];
240     } else if (mapSize.y > 400) {
241       markerPosition = [mapSize.x / 2, 400];
242     } else {
243       markerPosition = [mapSize.x / 2, mapSize.y];
244     }
245
246     newNote = L.marker(map.containerPointToLatLng(markerPosition), {
247       icon: noteIcons["new"],
248       opacity: 0.9,
249       draggable: true
250     });
251
252     var popupContent = $(JST["templates/notes/new"]({
253         create_url: $(e.target).attr("href")
254     }));
255
256     popupContent.find("textarea").on("input", disableWhenBlank);
257
258     function disableWhenBlank(e) {
259       $(e.target.form).prop("disabled", $(e.target).val() === "");
260     }
261
262     popupContent.find("input[type=submit]").on("click", function (e) {
263       e.preventDefault();
264       createNote(newNote, e.target.form, $(e.target).data("url"));
265     });
266
267     newNote.addTo(noteLayer).bindPopup(popupContent[0], popupOptions()).openPopup();
268
269     newNote.on("remove", function (e) {
270       $("#createnoteanchor").removeClass("disabled").addClass("geolink");
271     }).on("dragstart", function (e) {
272       $(newNote).stopTime("removenote");
273     }).on("dragend", function (e) {
274       e.target.openPopup();
275     });
276   });
277 });