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