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