Fixed failing test
[phpmyadmin.git] / js / gis_data_editor.js
blobbdd896459c4b6f992cb8bdb58fc3dfa2802f82b5
1 /* vim: set expandtab sw=4 ts=4 sts=4: */
2 /**
3  * @fileoverview    functions used in GIS data editor
4  *
5  * @requires    jQuery
6  *
7  */
9 var gisEditorLoaded = false;
11 /**
12  * Closes the GIS data editor and perform necessary clean up work.
13  */
14 function closeGISEditor() {
15     $("#popup_background").fadeOut("fast");
16     $("#gis_editor").fadeOut("fast", function () {
17         $(this).empty();
18     });
21 /**
22  * Prepares the HTML recieved via AJAX.
23  */
24 function prepareJSVersion() {
25     // Change the text on the submit button
26     $("#gis_editor input[name='gis_data[save]']")
27         .val(PMA_messages.strCopy)
28         .insertAfter($('#gis_data_textarea'))
29         .before('<br/><br/>');
31     // Add close and cancel links
32     $('#gis_data_editor').prepend('<a class="close_gis_editor" href="#">' + PMA_messages.strClose + '</a>');
33     $('<a class="cancel_gis_editor" href="#"> ' + PMA_messages.strCancel + '</a>')
34         .insertAfter($("input[name='gis_data[save]']"));
36     // Remove the unnecessary text
37     $('div#gis_data_output p').remove();
39     // Remove 'add' buttons and add links
40     $('#gis_editor input.add').each(function (e) {
41         var $button = $(this);
42         $button.addClass('addJs').removeClass('add');
43         var classes = $button.attr('class');
44         $button.replaceWith(
45             '<a class="' + classes +
46             '" name="' + $button.attr('name') +
47             '" href="#">+ ' + $button.val() + '</a>'
48         );
49     });
52 /**
53  * Returns the HTML for a data point.
54  *
55  * @param pointNumber point number
56  * @param prefix      prefix of the name
57  * @returns the HTML for a data point
58  */
59 function addDataPoint(pointNumber, prefix) {
60     return '<br/>' +
61         $.sprintf(PMA_messages.strPointN, (pointNumber + 1)) + ': ' +
62         '<label for="x">' + PMA_messages.strX + '</label>' +
63         '<input type="text" name="' + prefix + '[' + pointNumber + '][x]" value=""/>' +
64         '<label for="y">' + PMA_messages.strY + '</label>' +
65         '<input type="text" name="' + prefix + '[' + pointNumber + '][y]" value=""/>';
68 /**
69  * Initialize the visualization in the GIS data editor.
70  */
71 function initGISEditorVisualization() {
72     // Loads either SVG or OSM visualization based on the choice
73     selectVisualization();
74     // Adds necessary styles to the div that coontains the openStreetMap
75     styleOSM();
76     // Loads the SVG element and make a reference to it
77     loadSVG();
78     // Adds controllers for zooming and panning
79     addZoomPanControllers();
80     zoomAndPan();
83 /**
84  * Loads JavaScript files and the GIS editor.
85  *
86  * @param value      current value of the geometry field
87  * @param field      field name
88  * @param type       geometry type
89  * @param input_name name of the input field
90  * @param token      token
91  */
92 function loadJSAndGISEditor(value, field, type, input_name, token) {
93     var head = document.getElementsByTagName('head')[0];
94     var script;
96     // Loads a set of small JS file needed for the GIS editor
97     var smallScripts = [ 'js/jquery/jquery.svg.js',
98                      'js/jquery/jquery.mousewheel.js',
99                      'js/jquery/jquery.event.drag-2.2.js',
100                      'js/tbl_gis_visualization.js' ];
102     for (var i = 0; i < smallScripts.length; i++) {
103         script = document.createElement('script');
104         script.type = 'text/javascript';
105         script.src = smallScripts[i];
106         head.appendChild(script);
107     }
109     // OpenLayers.js is BIG and takes time. So asynchronous loading would not work.
110     // Load the JS and do a callback to load the content for the GIS Editor.
111     script = document.createElement('script');
112     script.type = 'text/javascript';
114     script.onreadystatechange = function () {
115         if (this.readyState == 'complete') {
116             loadGISEditor(value, field, type, input_name, token);
117         }
118     };
119     script.onload = function () {
120         loadGISEditor(value, field, type, input_name, token);
121     };
123     script.src = 'js/openlayers/OpenLayers.js';
124     head.appendChild(script);
126     gisEditorLoaded = true;
130  * Loads the GIS editor via AJAX
132  * @param value      current value of the geometry field
133  * @param field      field name
134  * @param type       geometry type
135  * @param input_name name of the input field
136  * @param token      token
137  */
138 function loadGISEditor(value, field, type, input_name, token) {
140     var $gis_editor = $("#gis_editor");
141     $.post('gis_data_editor.php', {
142         'field' : field,
143         'value' : value,
144         'type' : type,
145         'input_name' : input_name,
146         'get_gis_editor' : true,
147         'token' : token,
148         'ajax_request': true
149     }, function (data) {
150         if (data.success === true) {
151             $gis_editor.html(data.gis_editor);
152             initGISEditorVisualization();
153             prepareJSVersion();
154         } else {
155             PMA_ajaxShowMessage(data.error, false);
156         }
157     }, 'json');
161  * Opens up the dialog for the GIS data editor.
162  */
163 function openGISEditor() {
165     // Center the popup
166     var windowWidth = document.documentElement.clientWidth;
167     var windowHeight = document.documentElement.clientHeight;
168     var popupWidth = windowWidth * 0.9;
169     var popupHeight = windowHeight * 0.9;
170     var popupOffsetTop = windowHeight / 2 - popupHeight / 2;
171     var popupOffsetLeft = windowWidth / 2 - popupWidth / 2;
173     var $gis_editor = $("#gis_editor");
174     var $backgrouond = $("#popup_background");
176     $gis_editor.css({"top": popupOffsetTop, "left": popupOffsetLeft, "width": popupWidth, "height": popupHeight});
177     $backgrouond.css({"opacity" : "0.7"});
179     $gis_editor.append(
180         '<div id="gis_data_editor">' +
181         '<img class="ajaxIcon" id="loadingMonitorIcon" src="' +
182         pmaThemeImage + 'ajax_clock_small.gif" alt=""/>' +
183         '</div>'
184     );
186     // Make it appear
187     $backgrouond.fadeIn("fast");
188     $gis_editor.fadeIn("fast");
192  * Prepare and insert the GIS data in Well Known Text format
193  * to the input field.
194  */
195 function insertDataAndClose() {
196     var $form = $('form#gis_data_editor_form');
197     var input_name = $form.find("input[name='input_name']").val();
199     $.post('gis_data_editor.php', $form.serialize() + "&generate=true&ajax_request=true", function (data) {
200         if (data.success === true) {
201             $("input[name='" + input_name + "']").val(data.result);
202         } else {
203             PMA_ajaxShowMessage(data.error, false);
204         }
205     }, 'json');
206     closeGISEditor();
210  * Unbind all event handlers before tearing down a page
211  */
212 AJAX.registerTeardown('gis_data_editor.js', function () {
213     $("#gis_editor input[name='gis_data[save]']").die('click');
214     $('#gis_editor').die('submit');
215     $('#gis_editor').find("input[type='text']").die('change');
216     $("#gis_editor select.gis_type").die('change');
217     $('#gis_editor a.close_gis_editor, #gis_editor a.cancel_gis_editor').die('click');
218     $('#gis_editor a.addJs.addPoint').die('click');
219     $('#gis_editor a.addLine.addJs').die('click');
220     $('#gis_editor a.addJs.addPolygon').die('click');
221     $('#gis_editor a.addJs.addGeom').die('click');
224 AJAX.registerOnload('gis_data_editor.js', function () {
226     // Remove the class that is added due to the URL being too long.
227     $('span.open_gis_editor a').removeClass('formLinkSubmit');
229     /**
230      * Prepares and insert the GIS data to the input field on clicking 'copy'.
231      */
232     $("#gis_editor input[name='gis_data[save]']").live('click', function (event) {
233         event.preventDefault();
234         insertDataAndClose();
235     });
237     /**
238      * Prepares and insert the GIS data to the input field on pressing 'enter'.
239      */
240     $('#gis_editor').live('submit', function (event) {
241         event.preventDefault();
242         insertDataAndClose();
243     });
245     /**
246      * Trigger asynchronous calls on data change and update the output.
247      */
248     $('#gis_editor').find("input[type='text']").live('change', function () {
249         var $form = $('form#gis_data_editor_form');
250         $.post('gis_data_editor.php', $form.serialize() + "&generate=true&ajax_request=true", function (data) {
251             if (data.success === true) {
252                 $('#gis_data_textarea').val(data.result);
253                 $('#placeholder').empty().removeClass('hasSVG').html(data.visualization);
254                 $('#openlayersmap').empty();
255                 eval(data.openLayers);
256                 initGISEditorVisualization();
257             } else {
258                 PMA_ajaxShowMessage(data.error, false);
259             }
260         }, 'json');
261     });
263     /**
264      * Update the form on change of the GIS type.
265      */
266     $("#gis_editor select.gis_type").live('change', function (event) {
267         var $gis_editor = $("#gis_editor");
268         var $form = $('form#gis_data_editor_form');
270         $.post('gis_data_editor.php', $form.serialize() + "&get_gis_editor=true&ajax_request=true", function (data) {
271             if (data.success === true) {
272                 $gis_editor.html(data.gis_editor);
273                 initGISEditorVisualization();
274                 prepareJSVersion();
275             } else {
276                 PMA_ajaxShowMessage(data.error, false);
277             }
278         }, 'json');
279     });
281     /**
282      * Handles closing of the GIS data editor.
283      */
284     $('#gis_editor a.close_gis_editor, #gis_editor a.cancel_gis_editor').live('click', function () {
285         closeGISEditor();
286     });
288     /**
289      * Handles adding data points
290      */
291     $('#gis_editor a.addJs.addPoint').live('click', function () {
292         var $a = $(this);
293         var name = $a.attr('name');
294         // Eg. name = gis_data[0][MULTIPOINT][add_point] => prefix = gis_data[0][MULTIPOINT]
295         var prefix = name.substr(0, name.length - 11);
296         // Find the number of points
297         var $noOfPointsInput = $("input[name='" + prefix + "[no_of_points]" + "']");
298         var noOfPoints = parseInt($noOfPointsInput.val(), 10);
299         // Add the new data point
300         var html = addDataPoint(noOfPoints, prefix);
301         $a.before(html);
302         $noOfPointsInput.val(noOfPoints + 1);
303     });
305     /**
306      * Handles adding linestrings and inner rings
307      */
308     $('#gis_editor a.addLine.addJs').live('click', function () {
309         var $a = $(this);
310         var name = $a.attr('name');
312         // Eg. name = gis_data[0][MULTILINESTRING][add_line] => prefix = gis_data[0][MULTILINESTRING]
313         var prefix = name.substr(0, name.length - 10);
314         var type = prefix.slice(prefix.lastIndexOf('[') + 1, prefix.lastIndexOf(']'));
316         // Find the number of lines
317         var $noOfLinesInput = $("input[name='" + prefix + "[no_of_lines]" + "']");
318         var noOfLines = parseInt($noOfLinesInput.val(), 10);
320         // Add the new linesting of inner ring based on the type
321         var html = '<br/>';
322         var noOfPoints;
323         if (type == 'MULTILINESTRING') {
324             html += PMA_messages.strLineString + ' ' + (noOfLines + 1) + ':';
325             noOfPoints = 2;
326         } else {
327             html += PMA_messages.strInnerRing + ' ' + noOfLines + ':';
328             noOfPoints = 4;
329         }
330         html += '<input type="hidden" name="' + prefix + '[' + noOfLines + '][no_of_points]" value="' + noOfPoints + '"/>';
331         for (var i = 0; i < noOfPoints; i++) {
332             html += addDataPoint(i, (prefix + '[' + noOfLines + ']'));
333         }
334         html += '<a class="addPoint addJs" name="' + prefix + '[' + noOfLines + '][add_point]" href="#">+ ' +
335             PMA_messages.strAddPoint + '</a><br/>';
337         $a.before(html);
338         $noOfLinesInput.val(noOfLines + 1);
339     });
341     /**
342      * Handles adding polygons
343      */
344     $('#gis_editor a.addJs.addPolygon').live('click', function () {
345         var $a = $(this);
346         var name = $a.attr('name');
347         // Eg. name = gis_data[0][MULTIPOLYGON][add_polygon] => prefix = gis_data[0][MULTIPOLYGON]
348         var prefix = name.substr(0, name.length - 13);
349         // Find the number of polygons
350         var $noOfPolygonsInput = $("input[name='" + prefix + "[no_of_polygons]" + "']");
351         var noOfPolygons = parseInt($noOfPolygonsInput.val(), 10);
353         // Add the new polygon
354         var html = PMA_messages.strPolygon + ' ' + (noOfPolygons + 1) + ':<br/>';
355         html += '<input type="hidden" name="' + prefix + '[' + noOfPolygons + '][no_of_lines]" value="1"/>' +
356             '<br/>' + PMA_messages.strOuterRing + ':' +
357             '<input type="hidden" name="' + prefix + '[' + noOfPolygons + '][0][no_of_points]" value="4"/>';
358         for (var i = 0; i < 4; i++) {
359             html += addDataPoint(i, (prefix + '[' + noOfPolygons + '][0]'));
360         }
361         html += '<a class="addPoint addJs" name="' + prefix + '[' + noOfPolygons + '][0][add_point]" href="#">+ ' +
362             PMA_messages.strAddPoint + '</a><br/>' +
363             '<a class="addLine addJs" name="' + prefix + '[' + noOfPolygons + '][add_line]" href="#">+ ' +
364             PMA_messages.strAddInnerRing + '</a><br/><br/>';
366         $a.before(html);
367         $noOfPolygonsInput.val(noOfPolygons + 1);
368     });
370     /**
371      * Handles adding geoms
372      */
373     $('#gis_editor a.addJs.addGeom').live('click', function () {
374         var $a = $(this);
375         var prefix = 'gis_data[GEOMETRYCOLLECTION]';
376         // Find the number of geoms
377         var $noOfGeomsInput = $("input[name='" + prefix + "[geom_count]" + "']");
378         var noOfGeoms = parseInt($noOfGeomsInput.val(), 10);
380         var html1 = PMA_messages.strGeometry + ' ' + (noOfGeoms + 1) + ':<br/>';
381         var $geomType = $("select[name='gis_data[" + (noOfGeoms - 1) + "][gis_type]']").clone();
382         $geomType.attr('name', 'gis_data[' + noOfGeoms + '][gis_type]').val('POINT');
383         var html2 = '<br/>' + PMA_messages.strPoint + ' :' +
384             '<label for="x"> ' + PMA_messages.strX + ' </label>' +
385             '<input type="text" name="gis_data[' + noOfGeoms + '][POINT][x]" value=""/>' +
386             '<label for="y"> ' + PMA_messages.strY + ' </label>' +
387             '<input type="text" name="gis_data[' + noOfGeoms + '][POINT][y]" value=""/>' +
388             '<br/><br/>';
390         $a.before(html1);
391         $geomType.insertBefore($a);
392         $a.before(html2);
393         $noOfGeomsInput.val(noOfGeoms + 1);
394     });