Disable dragging of new notes once they are submitted
[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("popupopen", function (e) {
45     $(e.popup._container).find(".comment").focus();
46   });
47
48   map.on("popupclose", function (e) {
49     if (newNote && e.popup == newNote._popup) {
50       $(newNote).oneTime(10, "removenote", function () {
51         map.removeLayer(newNote);
52         newNote = null;
53       });
54     }
55   });
56
57   if (OSM.STATUS != 'api_offline' && OSM.STATUS != 'database_offline') {
58     map.layersControl.addOverlay(noteLayer, I18n.t("browse.start_rjs.notes_layer_name"));
59
60     if (params.notes) map.addLayer(noteLayer);
61
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     {
80       marker.setIcon(noteIcons[feature.properties.status]);
81       marker._popup.setContent(createPopupContent(marker, feature.properties));
82     }
83     else
84     {
85       marker = L.marker(feature.geometry.coordinates.reverse(), {
86         icon: noteIcons[feature.properties.status],
87         opacity: 0.7
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.toBBOX();
107
108       if (noteLoader) noteLoader.abort();
109
110       noteLoader = $.ajax({
111         url: url,
112         success: function (json) {
113           var oldNotes = notes;
114
115           notes = {};
116
117           json.features.forEach(function (feature) {
118             var marker = oldNotes[feature.properties.id];
119
120             delete oldNotes[feature.properties.id];
121
122             notes[feature.properties.id] = updateMarker(marker, feature);
123           });
124
125           for (id in oldNotes) {
126             noteLayer.removeLayer(oldNotes[id]);
127           }
128
129           noteLoader = null;
130         }
131       });
132     }
133   };
134
135   function popupOptions() {
136     var mapSize = map.getSize();
137
138     return {
139       minWidth: 320,
140       maxWidth: mapSize.y * 1 / 3,
141       maxHeight: mapSize.y * 2 / 3,
142       offset: new L.Point(0, -3),
143       autoPanPadding: new L.Point(60, 40)
144     };
145   }
146
147   function createPopupContent(marker, properties) {
148     var content = $(JST["templates/notes/show"]({ note: properties }));
149
150     content.find("textarea").on("input", function (e) {
151       var form = e.target.form;
152
153       if ($(e.target).val() == "") {
154         $(form.close).val(I18n.t("javascripts.notes.show.resolve"));
155         $(form.comment).prop("disabled", true);
156       } else {
157         $(form.close).val(I18n.t("javascripts.notes.show.comment_and_resolve"));
158         $(form.comment).prop("disabled", false);
159       }
160     });
161
162     content.find("input[type=submit]").on("click", function (e) {
163       e.preventDefault();
164       var data = $(e.target).data();
165       updateNote(marker, e.target.form, data.method, data.url);
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: function (feature) {
189         notes[feature.properties.id] = updateMarker(marker, feature);
190         newNote = null;
191
192         $("#createnoteanchor").removeClass("disabled").addClass("geolink");
193       }
194     });
195   }
196
197   function updateNote(marker, form, method, url) {
198     $(form).find("input[type=submit]").prop("disabled", true);
199
200     $.ajax({
201       url: url,
202       type: method,
203       oauth: true,
204       data: {
205         text: $(form.text).val()
206       },
207       success: function (feature) {
208         if (feature.properties.status == "hidden") {
209           noteLayer.removeLayer(marker);
210
211           delete notes[feature.properties.id];
212         } else {
213           var popupContent = createPopupContent(marker, feature.properties);
214
215           marker.setIcon(noteIcons[feature.properties.status]);
216           marker._popup.setContent(popupContent);
217         }
218       }
219     });
220   }
221
222   $("#createnoteanchor").click(function (e) {
223     e.preventDefault();
224
225     if ($(e.target).hasClass("disabled")) return;
226
227     $(e.target).removeClass("geolink").addClass("disabled");
228
229     map.addLayer(noteLayer);
230
231     var mapSize = map.getSize();
232     var markerPosition;
233
234     if (mapSize.y > 800)
235     {
236       markerPosition = [mapSize.x / 2, mapSize.y / 2];
237     }
238     else if (mapSize.y > 400)
239     {
240       markerPosition = [mapSize.x / 2, 400];
241     }
242     else
243     {
244       markerPosition = [mapSize.x / 2, mapSize.y];
245     }
246
247     newNote = L.marker(map.containerPointToLatLng(markerPosition), {
248       icon: noteIcons["new"],
249       opacity: 0.7,
250       draggable: true
251     });
252
253     var popupContent = $(JST["templates/notes/new"]({ create_url: $(e.target).attr("href") }));
254
255     popupContent.find("textarea").on("input", function (e) {
256       var form = e.target.form;
257
258       if ($(e.target).val() == "") {
259         $(form.add).prop("disabled", true);
260       } else {
261         $(form.add).prop("disabled", false);
262       }
263     });
264
265     popupContent.find("input[type=submit]").on("click", function (e) {
266       e.preventDefault();
267       createNote(newNote, e.target.form, $(e.target).data("url"));
268     });
269
270     newNote.addTo(noteLayer).bindPopup(popupContent[0], popupOptions()).openPopup();
271
272     newNote.on("remove", function (e) {
273       $("#createnoteanchor").removeClass("disabled").addClass("geolink");
274     });
275
276     newNote.on("dragstart", function (e) {
277       $(newNote).stopTime("removenote");
278     });
279
280     newNote.on("dragend", function (e) {
281       e.target.openPopup();
282     });
283   });
284 });