Translated using Weblate (Korean)
[phpmyadmin.git] / js / tbl_select.js
blobb1603f9849c5d6459904759d558b19e95779fb7c
1 /* vim: set expandtab sw=4 ts=4 sts=4: */
2 /**
3  * @fileoverview JavaScript functions used on tbl_select.php
4  *
5  * @requires    jQuery
6  * @requires    js/functions.js
7  */
9 /**
10  * Ajax event handlers for this page
11  *
12  * Actions ajaxified here:
13  * Table search
14  */
16 /**
17  * Checks if given data-type is numeric or date.
18  *
19  * @param string data_type Column data-type
20  *
21  * @return bool|string
22  */
23 function PMA_checkIfDataTypeNumericOrDate(data_type)
25     // To test for numeric data-types.
26     var numeric_re = new RegExp(
27         'TINYINT|SMALLINT|MEDIUMINT|INT|BIGINT|DECIMAL|FLOAT|DOUBLE|REAL',
28         'i'
29     );
31     // To test for date data-types.
32     var date_re = new RegExp(
33         'DATETIME|DATE|TIMESTAMP|TIME|YEAR',
34         'i'
35     );
37     // Return matched data-type
38     if (numeric_re.test(data_type)) {
39         return numeric_re.exec(data_type)[0];
40     }
42     if (date_re.test(data_type)) {
43         return date_re.exec(data_type)[0];
44     }
46     return false;
49 /**
50  * Unbind all event handlers before tearing down a page
51  */
52 AJAX.registerTeardown('tbl_select.js', function () {
53     $('#togglesearchformlink').unbind('click');
54     $(document).off('submit', "#tbl_search_form.ajax");
55     $('select.geom_func').unbind('change');
56     $(document).off('click', 'span.open_search_gis_editor');
57     $('body').off('click', 'select[name*="criteriaColumnOperators"]');
58 });
60 AJAX.registerOnload('tbl_select.js', function () {
61     /**
62      * Prepare a div containing a link, otherwise it's incorrectly displayed
63      * after a couple of clicks
64      */
65     $('<div id="togglesearchformdiv"><a id="togglesearchformlink"></a></div>')
66         .insertAfter('#tbl_search_form')
67         // don't show it until we have results on-screen
68         .hide();
70     $('#togglesearchformlink')
71         .html(PMA_messages.strShowSearchCriteria)
72         .bind('click', function () {
73             var $link = $(this);
74             $('#tbl_search_form').slideToggle();
75             if ($link.text() == PMA_messages.strHideSearchCriteria) {
76                 $link.text(PMA_messages.strShowSearchCriteria);
77             } else {
78                 $link.text(PMA_messages.strHideSearchCriteria);
79             }
80             // avoid default click action
81             return false;
82         });
84     /**
85      * Ajax event handler for Table search
86      */
87     $(document).on('submit', "#tbl_search_form.ajax", function (event) {
88         var unaryFunctions = [
89             'IS NULL',
90             'IS NOT NULL',
91             "= ''",
92             "!= ''"
93         ];
95         var geomUnaryFunctions = [
96             'IsEmpty',
97             'IsSimple',
98             'IsRing',
99             'IsClosed',
100         ];
102         // jQuery object to reuse
103         var $search_form = $(this);
104         event.preventDefault();
106         // empty previous search results while we are waiting for new results
107         $("#sqlqueryresultsouter").empty();
108         var $msgbox = PMA_ajaxShowMessage(PMA_messages.strSearching, false);
110         PMA_prepareForAjaxRequest($search_form);
112         var values = {};
113         $search_form.find(':input').each(function () {
114             var $input = $(this);
115             if ($input.attr('type') == 'checkbox' || $input.attr('type') == 'radio') {
116                 if ($input.is(':checked')) {
117                     values[this.name] = $input.val();
118                 }
119             } else {
120                 values[this.name] = $input.val();
121             }
122         });
123         var columnCount = $('select[name="columnsToDisplay[]"] option').length;
124         // Submit values only for the columns that have unary column operator or a search criteria
125         for (var a = 0; a < columnCount; a++) {
126             if ($.inArray(values['criteriaColumnOperators[' + a + ']'], unaryFunctions) >= 0) {
127                 continue;
128             }
130             if (values['geom_func[' + a + ']'] &&
131                 $.isArray(values['geom_func[' + a + ']'], geomUnaryFunctions) >= 0) {
132                 continue;
133             }
135             if (values['criteriaValues[' + a + ']'] === '' || values['criteriaValues[' + a + ']'] === null) {
136                 delete values['criteriaValues[' + a + ']'];
137                 delete values['criteriaColumnOperators[' + a + ']'];
138                 delete values['criteriaColumnNames[' + a + ']'];
139                 delete values['criteriaColumnTypes[' + a + ']'];
140                 delete values['criteriaColumnCollations[' + a + ']'];
141             }
142         }
143         // If all columns are selected, use a single parameter to indicate that
144         if (values['columnsToDisplay[]'] !== null) {
145             if (values['columnsToDisplay[]'].length == columnCount) {
146                 delete values['columnsToDisplay[]'];
147                 values.displayAllColumns = true;
148             }
149         } else {
150             values.displayAllColumns = true;
151         }
153         $.post($search_form.attr('action'), values, function (data) {
154             PMA_ajaxRemoveMessage($msgbox);
155             if (typeof data !== 'undefined' && data.success === true) {
156                 if (typeof data.sql_query !== 'undefined') { // zero rows
157                     $("#sqlqueryresultsouter").html(data.sql_query);
158                 } else { // results found
159                     $("#sqlqueryresultsouter").html(data.message);
160                     $(".sqlqueryresults").trigger('makegrid').trigger('stickycolumns');
161                 }
162                 $('#tbl_search_form')
163                     // workaround for bug #3168569 - Issue on toggling the "Hide search criteria" in chrome.
164                     .slideToggle()
165                     .hide();
166                 $('#togglesearchformlink')
167                     // always start with the Show message
168                     .text(PMA_messages.strShowSearchCriteria);
169                 $('#togglesearchformdiv')
170                     // now it's time to show the div containing the link
171                     .show();
172                 // needed for the display options slider in the results
173                 PMA_init_slider();
174                 $('html, body').animate({scrollTop: 0}, 'fast');
175             } else {
176                 $("#sqlqueryresultsouter").html(data.error);
177             }
178             PMA_highlightSQL($('#sqlqueryresultsouter'));
179         }); // end $.post()
180     });
182     // Following section is related to the 'function based search' for geometry data types.
183     // Initialy hide all the open_gis_editor spans
184     $('span.open_search_gis_editor').hide();
186     $('select.geom_func').bind('change', function () {
187         var $geomFuncSelector = $(this);
189         var binaryFunctions = [
190             'Contains',
191             'Crosses',
192             'Disjoint',
193             'Equals',
194             'Intersects',
195             'Overlaps',
196             'Touches',
197             'Within',
198             'MBRContains',
199             'MBRDisjoint',
200             'MBREquals',
201             'MBRIntersects',
202             'MBROverlaps',
203             'MBRTouches',
204             'MBRWithin',
205             'ST_Contains',
206             'ST_Crosses',
207             'ST_Disjoint',
208             'ST_Equals',
209             'ST_Intersects',
210             'ST_Overlaps',
211             'ST_Touches',
212             'ST_Within'
213         ];
215         var tempArray = [
216             'Envelope',
217             'EndPoint',
218             'StartPoint',
219             'ExteriorRing',
220             'Centroid',
221             'PointOnSurface'
222         ];
223         var outputGeomFunctions = binaryFunctions.concat(tempArray);
225         // If the chosen function takes two geometry objects as parameters
226         var $operator = $geomFuncSelector.parents('tr').find('td:nth-child(5)').find('select');
227         if ($.inArray($geomFuncSelector.val(), binaryFunctions) >= 0) {
228             $operator.prop('readonly', true);
229         } else {
230             $operator.prop('readonly', false);
231         }
233         // if the chosen function's output is a geometry, enable GIS editor
234         var $editorSpan = $geomFuncSelector.parents('tr').find('span.open_search_gis_editor');
235         if ($.inArray($geomFuncSelector.val(), outputGeomFunctions) >= 0) {
236             $editorSpan.show();
237         } else {
238             $editorSpan.hide();
239         }
241     });
243     $(document).on('click', 'span.open_search_gis_editor', function (event) {
244         event.preventDefault();
246         var $span = $(this);
247         // Current value
248         var value = $span.parent('td').children("input[type='text']").val();
249         // Field name
250         var field = 'Parameter';
251         // Column type
252         var geom_func = $span.parents('tr').find('.geom_func').val();
253         var type;
254         if (geom_func == 'Envelope') {
255             type = 'polygon';
256         } else if (geom_func == 'ExteriorRing') {
257             type = 'linestring';
258         } else {
259             type = 'point';
260         }
261         // Names of input field and null checkbox
262         var input_name = $span.parent('td').children("input[type='text']").attr('name');
263         //Token
264         var token = $("input[name='token']").val();
266         openGISEditor();
267         if (!gisEditorLoaded) {
268             loadJSAndGISEditor(value, field, type, input_name, token);
269         } else {
270             loadGISEditor(value, field, type, input_name, token);
271         }
272     });
274     /**
275      * Ajax event handler for Range-Search.
276      */
277     $('body').on('click', 'select[name*="criteriaColumnOperators"]', function () {
278         $source_select = $(this);
279         // Get the column name.
280         var column_name = $(this)
281             .closest('tr')
282             .find('th:first')
283             .text();
285         // Get the data-type of column excluding size.
286         var data_type = $(this)
287             .closest('tr')
288             .find('td[data-type]')
289             .attr('data-type');
290         data_type = PMA_checkIfDataTypeNumericOrDate(data_type);
292         // Get the operator.
293         var operator = $(this).val();
295         if ((operator == 'BETWEEN' || operator == 'NOT BETWEEN')
296             && data_type
297         ) {
298             var $msgbox = PMA_ajaxShowMessage();
299             $.ajax({
300                 url: 'tbl_select.php',
301                 type: 'POST',
302                 data: {
303                     token: $('input[name="token"]').val(),
304                     ajax_request: 1,
305                     db: $('input[name="db"]').val(),
306                     table: $('input[name="table"]').val(),
307                     column: column_name,
308                     range_search: 1
309                 },
310                 success: function (response) {
311                     PMA_ajaxRemoveMessage($msgbox);
312                     if (response.success) {
313                         // Get the column min value.
314                         var min = response.column_data.min
315                             ? '(' + PMA_messages.strColumnMin +
316                                 ' ' + response.column_data.min + ')'
317                             : '';
318                         // Get the column max value.
319                         var max = response.column_data.max
320                             ? '(' + PMA_messages.strColumnMax +
321                                 ' ' + response.column_data.max + ')'
322                             : '';
323                         var button_options = {};
324                         button_options[PMA_messages.strGo] = function () {
325                             var min_value = $('#min_value').val();
326                             var max_value = $('#max_value').val();
327                             var final_value = '';
328                             if (min_value.length && max_value.length) {
329                                 final_value = min_value + ', ' +
330                                     max_value;
331                             }
332                             var $target_field = $source_select.closest('tr')
333                                 .find('[name*="criteriaValues"]');
335                             // If target field is a select list.
336                             if ($target_field.is('select')) {
337                                 $target_field.val(final_value);
338                                 var $options = $target_field.find('option');
339                                 var $closest_min = null;
340                                 var $closest_max = null;
341                                 // Find closest min and max value.
342                                 $options.each(function () {
343                                     if (
344                                         $closest_min === null
345                                         || Math.abs($(this).val() - min_value) < Math.abs($closest_min.val() - min_value)
346                                     ) {
347                                         $closest_min = $(this);
348                                     }
350                                     if (
351                                         $closest_max === null
352                                         || Math.abs($(this).val() - max_value) < Math.abs($closest_max.val() - max_value)
353                                     ) {
354                                         $closest_max = $(this);
355                                     }
356                                 });
358                                 $closest_min.attr('selected', 'selected');
359                                 $closest_max.attr('selected', 'selected');
360                             } else {
361                                 $target_field.val(final_value);
362                             }
363                             $(this).dialog("close");
364                         };
365                         button_options[PMA_messages.strCancel] = function () {
366                             $(this).dialog("close");
367                         };
369                         // Display dialog box.
370                         $('<div/>').append(
371                             '<fieldset>' +
372                             '<legend>' + operator + '</legend>' +
373                             '<lablel for="min_value">' + PMA_messages.strMinValue +
374                             '</label>' +
375                             '<input type="text" id="min_value" />' + '<br>' +
376                             '<span class="small_font">' + min + '</span>' + '<br>' +
377                             '<lablel for="max_value">' + PMA_messages.strMaxValue +
378                             '</label>' +
379                             '<input type="text" id="max_value" />' + '<br>' +
380                             '<span class="small_font">' + max + '</span>' +
381                             '</fieldset>'
382                         ).dialog({
383                             minWidth: 500,
384                             maxHeight: 400,
385                             modal: true,
386                             buttons: button_options,
387                             title: PMA_messages.strRangeSearch,
388                             open: function () {
389                                 // Add datepicker wherever required.
390                                 PMA_addDatepicker($('#min_value'), data_type);
391                                 PMA_addDatepicker($('#max_value'), data_type);
392                             },
393                             close: function () {
394                                 $(this).remove();
395                             }
396                         });
397                     } else {
398                         PMA_ajaxShowMessage(response.error);
399                     }
400                 },
401                 error: function (response) {
402                     PMA_ajaxShowMessage(PMA_messages.strErrorProcessingRequest);
403                 }
404             });
405         }
406     });