a623a51a2a7fce29bf52bd8af0d949af90977c0b
[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       data: {
175         lat: location.lat,
176         lon: location.lng,
177         text: $(form.text).val()
178       },
179       success: function (feature) {
180         notes[feature.properties.id] = updateMarker(marker, feature);
181         newNote = null;
182
183         $("#createnoteanchor").removeClass("disabled").addClass("geolink");
184       }
185     });
186   }
187
188   function updateNote(marker, form, url) {
189     $(form).find("input[type=submit]").prop("disabled", true);
190
191     $.ajax({
192       url: url,
193       type: "POST",
194       data: {
195         text: $(form.text).val()
196       },
197       success: function (feature) {
198         var popupContent = createPopupContent(marker, feature.properties);
199
200         marker.setIcon(noteIcons[feature.properties.status]);
201         marker._popup.setContent(popupContent);
202       }
203     });
204   }
205
206   $("#createnoteanchor").click(function (e) {
207     e.preventDefault();
208
209     if ($(e.target).hasClass("disabled")) return;
210
211     $(e.target).removeClass("geolink").addClass("disabled");
212
213     map.addLayer(noteLayer);
214
215     var mapSize = map.getSize();
216     var markerPosition;
217
218     if (mapSize.y > 800)
219     {
220       markerPosition = [mapSize.x / 2, mapSize.y / 2];
221     }
222     else if (mapSize.y > 400)
223     {
224       markerPosition = [mapSize.x / 2, 400];
225     }
226     else
227     {
228       markerPosition = [mapSize.x / 2, mapSize.y];
229     }
230
231     newNote = L.marker(map.containerPointToLatLng(markerPosition), {
232       icon: noteIcons["new"],
233       opacity: 0.7,
234       draggable: true
235     });
236
237     var popupContent = $(JST["templates/notes/new"]({ create_url: $(e.target).attr("href") }));
238
239     popupContent.find("textarea").on("input", function (e) {
240       var form = e.target.form;
241
242       if ($(e.target).val() == "") {
243         $(form.add).prop("disabled", true);
244       } else {
245         $(form.add).prop("disabled", false);
246       }
247     });
248
249     popupContent.find("input[type=submit]").on("click", function (e) {
250       e.preventDefault();
251       createNote(newNote, e.target.form, $(e.target).data("url"));
252     });
253
254     newNote.addTo(noteLayer).bindPopup(popupContent[0], popupOptions()).openPopup();
255
256     newNote.on("remove", function (e) {
257       $("#createnoteanchor").removeClass("disabled").addClass("geolink");
258     });
259
260     newNote.on("dragstart", function (e) {
261       $(newNote).stopTime("removenote");
262     });
263
264     newNote.on("dragend", function (e) {
265       e.target.openPopup();
266     });
267   });
268 });