Translated using Weblate (Czech)
[phpmyadmin.git] / js / gis_data_editor.js
blobdb73243d0aa5f77d818dce9fe9a6685c68653bed
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 /* global addZoomPanControllers, loadSVG, selectVisualization, styleOSM, zoomAndPan */ // js/table/gis_visualization.js
10 /* global pmaThemeImage */ // js/messages.php
12 // eslint-disable-next-line no-unused-vars
13 var gisEditorLoaded = false;
15 /**
16  * Closes the GIS data editor and perform necessary clean up work.
17  */
18 function closeGISEditor () {
19     $('#popup_background').fadeOut('fast');
20     $('#gis_editor').fadeOut('fast', function () {
21         $(this).empty();
22     });
25 /**
26  * Prepares the HTML received via AJAX.
27  */
28 function prepareJSVersion () {
29     // Change the text on the submit button
30     $('#gis_editor').find('input[name=\'gis_data[save]\']')
31         .val(Messages.strCopy)
32         .insertAfter($('#gis_data_textarea'))
33         .before('<br><br>');
35     // Add close and cancel links
36     $('#gis_data_editor').prepend('<a class="close_gis_editor" href="#">' + Messages.strClose + '</a>');
37     $('<a class="cancel_gis_editor" href="#"> ' + Messages.strCancel + '</a>')
38         .insertAfter($('input[name=\'gis_data[save]\']'));
40     // Remove the unnecessary text
41     $('div#gis_data_output p').remove();
43     // Remove 'add' buttons and add links
44     $('#gis_editor').find('input.add').each(function () {
45         var $button = $(this);
46         $button.addClass('addJs').removeClass('add');
47         var classes = $button.attr('class');
48         $button.replaceWith(
49             '<a class="' + classes +
50             '" name="' + $button.attr('name') +
51             '" href="#">+ ' + $button.val() + '</a>'
52         );
53     });
56 /**
57  * Returns the HTML for a data point.
58  *
59  * @param pointNumber point number
60  * @param prefix      prefix of the name
61  * @returns the HTML for a data point
62  */
63 function addDataPoint (pointNumber, prefix) {
64     return '<br>' +
65         Functions.sprintf(Messages.strPointN, (pointNumber + 1)) + ': ' +
66         '<label for="x">' + Messages.strX + '</label>' +
67         '<input type="text" name="' + prefix + '[' + pointNumber + '][x]" value="">' +
68         '<label for="y">' + Messages.strY + '</label>' +
69         '<input type="text" name="' + prefix + '[' + pointNumber + '][y]" value="">';
72 /**
73  * Initialize the visualization in the GIS data editor.
74  */
75 function initGISEditorVisualization () {
76     // Loads either SVG or OSM visualization based on the choice
77     selectVisualization();
78     // Adds necessary styles to the div that coontains the openStreetMap
79     styleOSM();
80     // Loads the SVG element and make a reference to it
81     loadSVG();
82     // Adds controllers for zooming and panning
83     addZoomPanControllers();
84     zoomAndPan();
87 /**
88  * Loads JavaScript files and the GIS editor.
89  *
90  * @param value      current value of the geometry field
91  * @param field      field name
92  * @param type       geometry type
93  * @param inputName name of the input field
94  * @param token      token
95  */
96 // eslint-disable-next-line no-unused-vars
97 function loadJSAndGISEditor (value, field, type, inputName) {
98     var head = document.getElementsByTagName('head')[0];
99     var script;
101     // Loads a set of small JS file needed for the GIS editor
102     var smallScripts = ['js/vendor/jquery/jquery.svg.js',
103         'js/vendor/jquery/jquery.mousewheel.js',
104         'js/vendor/jquery/jquery.event.drag-2.2.js',
105         'js/table/gis_visualization.js'];
107     for (var i = 0; i < smallScripts.length; i++) {
108         script = document.createElement('script');
109         script.type = 'text/javascript';
110         script.src = smallScripts[i];
111         head.appendChild(script);
112     }
114     // OpenLayers.js is BIG and takes time. So asynchronous loading would not work.
115     // Load the JS and do a callback to load the content for the GIS Editor.
116     script = document.createElement('script');
117     script.type = 'text/javascript';
119     script.onreadystatechange = function () {
120         if (this.readyState === 'complete') {
121             loadGISEditor(value, field, type, inputName);
122         }
123     };
124     script.onload = function () {
125         loadGISEditor(value, field, type, inputName);
126     };
127     script.onerror = function () {
128         loadGISEditor(value, field, type, inputName);
129     };
131     script.src = 'js/vendor/openlayers/OpenLayers.js';
132     head.appendChild(script);
134     gisEditorLoaded = true;
138  * Loads the GIS editor via AJAX
140  * @param value      current value of the geometry field
141  * @param field      field name
142  * @param type       geometry type
143  * @param inputName name of the input field
144  */
145 function loadGISEditor (value, field, type, inputName) {
146     var $gisEditor = $('#gis_editor');
147     $.post('gis_data_editor.php', {
148         'field' : field,
149         'value' : value,
150         'type' : type,
151         'input_name' : inputName,
152         'get_gis_editor' : true,
153         'ajax_request': true,
154         'server': CommonParams.get('server')
155     }, function (data) {
156         if (typeof data !== 'undefined' && data.success === true) {
157             $gisEditor.html(data.gis_editor);
158             initGISEditorVisualization();
159             prepareJSVersion();
160         } else {
161             Functions.ajaxShowMessage(data.error, false);
162         }
163     }, 'json');
167  * Opens up the dialog for the GIS data editor.
168  */
169 // eslint-disable-next-line no-unused-vars
170 function openGISEditor () {
171     // Center the popup
172     var windowWidth = document.documentElement.clientWidth;
173     var windowHeight = document.documentElement.clientHeight;
174     var popupWidth = windowWidth * 0.9;
175     var popupHeight = windowHeight * 0.9;
176     var popupOffsetTop = windowHeight / 2 - popupHeight / 2;
177     var popupOffsetLeft = windowWidth / 2 - popupWidth / 2;
179     var $gisEditor = $('#gis_editor');
180     var $backgrouond = $('#popup_background');
182     $gisEditor.css({ 'top': popupOffsetTop, 'left': popupOffsetLeft, 'width': popupWidth, 'height': popupHeight });
183     $backgrouond.css({ 'opacity' : '0.7' });
185     $gisEditor.append(
186         '<div id="gis_data_editor">' +
187         '<img class="ajaxIcon" id="loadingMonitorIcon" src="' +
188         pmaThemeImage + 'ajax_clock_small.gif" alt="">' +
189         '</div>'
190     );
192     // Make it appear
193     $backgrouond.fadeIn('fast');
194     $gisEditor.fadeIn('fast');
198  * Prepare and insert the GIS data in Well Known Text format
199  * to the input field.
200  */
201 function insertDataAndClose () {
202     var $form = $('form#gis_data_editor_form');
203     var inputName = $form.find('input[name=\'input_name\']').val();
205     var argsep = CommonParams.get('arg_separator');
206     $.post('gis_data_editor.php', $form.serialize() + argsep + 'generate=true' + argsep + 'ajax_request=true', function (data) {
207         if (typeof data !== 'undefined' && data.success === true) {
208             $('input[name=\'' + inputName + '\']').val(data.result);
209         } else {
210             Functions.ajaxShowMessage(data.error, false);
211         }
212     }, 'json');
213     closeGISEditor();
217  * Unbind all event handlers before tearing down a page
218  */
219 AJAX.registerTeardown('gis_data_editor.js', function () {
220     $(document).off('click', '#gis_editor input[name=\'gis_data[save]\']');
221     $(document).off('submit', '#gis_editor');
222     $(document).off('change', '#gis_editor input[type=\'text\']');
223     $(document).off('change', '#gis_editor select.gis_type');
224     $(document).off('click', '#gis_editor a.close_gis_editor, #gis_editor a.cancel_gis_editor');
225     $(document).off('click', '#gis_editor a.addJs.addPoint');
226     $(document).off('click', '#gis_editor a.addLine.addJs');
227     $(document).off('click', '#gis_editor a.addJs.addPolygon');
228     $(document).off('click', '#gis_editor a.addJs.addGeom');
231 AJAX.registerOnload('gis_data_editor.js', function () {
232     /**
233      * Prepares and insert the GIS data to the input field on clicking 'copy'.
234      */
235     $(document).on('click', '#gis_editor input[name=\'gis_data[save]\']', function (event) {
236         event.preventDefault();
237         insertDataAndClose();
238     });
240     /**
241      * Prepares and insert the GIS data to the input field on pressing 'enter'.
242      */
243     $(document).on('submit', '#gis_editor', function (event) {
244         event.preventDefault();
245         insertDataAndClose();
246     });
248     /**
249      * Trigger asynchronous calls on data change and update the output.
250      */
251     $(document).on('change', '#gis_editor input[type=\'text\']', function () {
252         var $form = $('form#gis_data_editor_form');
253         var argsep = CommonParams.get('arg_separator');
254         $.post('gis_data_editor.php', $form.serialize() + argsep + 'generate=true' + argsep + 'ajax_request=true', function (data) {
255             if (typeof data !== 'undefined' && data.success === true) {
256                 $('#gis_data_textarea').val(data.result);
257                 $('#placeholder').empty().removeClass('hasSVG').html(data.visualization);
258                 $('#openlayersmap').empty();
259                 /* TODO: the gis_data_editor should rather return JSON than JS code to eval */
260                 // eslint-disable-next-line no-eval
261                 eval(data.openLayers);
262                 initGISEditorVisualization();
263             } else {
264                 Functions.ajaxShowMessage(data.error, false);
265             }
266         }, 'json');
267     });
269     /**
270      * Update the form on change of the GIS type.
271      */
272     $(document).on('change', '#gis_editor select.gis_type', function () {
273         var $gisEditor = $('#gis_editor');
274         var $form = $('form#gis_data_editor_form');
276         var argsep = CommonParams.get('arg_separator');
277         $.post('gis_data_editor.php', $form.serialize() + argsep + 'get_gis_editor=true' + argsep + 'ajax_request=true', function (data) {
278             if (typeof data !== 'undefined' && data.success === true) {
279                 $gisEditor.html(data.gis_editor);
280                 initGISEditorVisualization();
281                 prepareJSVersion();
282             } else {
283                 Functions.ajaxShowMessage(data.error, false);
284             }
285         }, 'json');
286     });
288     /**
289      * Handles closing of the GIS data editor.
290      */
291     $(document).on('click', '#gis_editor a.close_gis_editor, #gis_editor a.cancel_gis_editor', function () {
292         closeGISEditor();
293     });
295     /**
296      * Handles adding data points
297      */
298     $(document).on('click', '#gis_editor a.addJs.addPoint', function () {
299         var $a = $(this);
300         var name = $a.attr('name');
301         // Eg. name = gis_data[0][MULTIPOINT][add_point] => prefix = gis_data[0][MULTIPOINT]
302         var prefix = name.substr(0, name.length - 11);
303         // Find the number of points
304         var $noOfPointsInput = $('input[name=\'' + prefix + '[no_of_points]' + '\']');
305         var noOfPoints = parseInt($noOfPointsInput.val(), 10);
306         // Add the new data point
307         var html = addDataPoint(noOfPoints, prefix);
308         $a.before(html);
309         $noOfPointsInput.val(noOfPoints + 1);
310     });
312     /**
313      * Handles adding linestrings and inner rings
314      */
315     $(document).on('click', '#gis_editor a.addLine.addJs', function () {
316         var $a = $(this);
317         var name = $a.attr('name');
319         // Eg. name = gis_data[0][MULTILINESTRING][add_line] => prefix = gis_data[0][MULTILINESTRING]
320         var prefix = name.substr(0, name.length - 10);
321         var type = prefix.slice(prefix.lastIndexOf('[') + 1, prefix.lastIndexOf(']'));
323         // Find the number of lines
324         var $noOfLinesInput = $('input[name=\'' + prefix + '[no_of_lines]' + '\']');
325         var noOfLines = parseInt($noOfLinesInput.val(), 10);
327         // Add the new linesting of inner ring based on the type
328         var html = '<br>';
329         var noOfPoints;
330         if (type === 'MULTILINESTRING') {
331             html += Messages.strLineString + ' ' + (noOfLines + 1) + ':';
332             noOfPoints = 2;
333         } else {
334             html += Messages.strInnerRing + ' ' + noOfLines + ':';
335             noOfPoints = 4;
336         }
337         html += '<input type="hidden" name="' + prefix + '[' + noOfLines + '][no_of_points]" value="' + noOfPoints + '">';
338         for (var i = 0; i < noOfPoints; i++) {
339             html += addDataPoint(i, (prefix + '[' + noOfLines + ']'));
340         }
341         html += '<a class="addPoint addJs" name="' + prefix + '[' + noOfLines + '][add_point]" href="#">+ ' +
342             Messages.strAddPoint + '</a><br>';
344         $a.before(html);
345         $noOfLinesInput.val(noOfLines + 1);
346     });
348     /**
349      * Handles adding polygons
350      */
351     $(document).on('click', '#gis_editor a.addJs.addPolygon', function () {
352         var $a = $(this);
353         var name = $a.attr('name');
354         // Eg. name = gis_data[0][MULTIPOLYGON][add_polygon] => prefix = gis_data[0][MULTIPOLYGON]
355         var prefix = name.substr(0, name.length - 13);
356         // Find the number of polygons
357         var $noOfPolygonsInput = $('input[name=\'' + prefix + '[no_of_polygons]' + '\']');
358         var noOfPolygons = parseInt($noOfPolygonsInput.val(), 10);
360         // Add the new polygon
361         var html = Messages.strPolygon + ' ' + (noOfPolygons + 1) + ':<br>';
362         html += '<input type="hidden" name="' + prefix + '[' + noOfPolygons + '][no_of_lines]" value="1">' +
363             '<br>' + Messages.strOuterRing + ':' +
364             '<input type="hidden" name="' + prefix + '[' + noOfPolygons + '][0][no_of_points]" value="4">';
365         for (var i = 0; i < 4; i++) {
366             html += addDataPoint(i, (prefix + '[' + noOfPolygons + '][0]'));
367         }
368         html += '<a class="addPoint addJs" name="' + prefix + '[' + noOfPolygons + '][0][add_point]" href="#">+ ' +
369             Messages.strAddPoint + '</a><br>' +
370             '<a class="addLine addJs" name="' + prefix + '[' + noOfPolygons + '][add_line]" href="#">+ ' +
371             Messages.strAddInnerRing + '</a><br><br>';
373         $a.before(html);
374         $noOfPolygonsInput.val(noOfPolygons + 1);
375     });
377     /**
378      * Handles adding geoms
379      */
380     $(document).on('click', '#gis_editor a.addJs.addGeom', function () {
381         var $a = $(this);
382         var prefix = 'gis_data[GEOMETRYCOLLECTION]';
383         // Find the number of geoms
384         var $noOfGeomsInput = $('input[name=\'' + prefix + '[geom_count]' + '\']');
385         var noOfGeoms = parseInt($noOfGeomsInput.val(), 10);
387         var html1 = Messages.strGeometry + ' ' + (noOfGeoms + 1) + ':<br>';
388         var $geomType = $('select[name=\'gis_data[' + (noOfGeoms - 1) + '][gis_type]\']').clone();
389         $geomType.attr('name', 'gis_data[' + noOfGeoms + '][gis_type]').val('POINT');
390         var html2 = '<br>' + Messages.strPoint + ' :' +
391             '<label for="x"> ' + Messages.strX + ' </label>' +
392             '<input type="text" name="gis_data[' + noOfGeoms + '][POINT][x]" value="">' +
393             '<label for="y"> ' + Messages.strY + ' </label>' +
394             '<input type="text" name="gis_data[' + noOfGeoms + '][POINT][y]" value="">' +
395             '<br><br>';
397         $a.before(html1);
398         $geomType.insertBefore($a);
399         $a.before(html2);
400         $noOfGeomsInput.val(noOfGeoms + 1);
401     });