Translated using Weblate (Hungarian)
[phpmyadmin.git] / js / indexes.js
blobdde9ef7dd0687f2670552a4cec88944a81246f57
1 /* vim: set expandtab sw=4 ts=4 sts=4: */
2 /**
3  * @fileoverview    function used for index manipulation pages
4  * @name            Table Structure
5  *
6  * @requires    jQuery
7  * @requires    jQueryUI
8  * @required    js/functions.js
9  */
11 /**
12  * Hides/shows the inputs and submits appropriately depending
13  * on whether the index type chosen is 'SPATIAL' or not.
14  */
15 function checkIndexType()
17     /**
18      * @var Object Dropdown to select the index type.
19      */
20     $select_index_type = $('#select_index_type');
21     /**
22      * @var Object Table header for the size column.
23      */
24     $size_header = $('#index_columns thead tr th:nth-child(2)');
25     /**
26      * @var Object Inputs to specify the columns for the index.
27      */
28     $column_inputs = $('select[name="index[columns][names][]"]');
29     /**
30      * @var Object Inputs to specify sizes for columns of the index.
31      */
32     $size_inputs = $('input[name="index[columns][sub_parts][]"]');
33     /**
34      * @var Object Footer containg the controllers to add more columns
35      */
36     $add_more = $('#index_frm .tblFooters');
38     if ($select_index_type.val() == 'SPATIAL') {
39         // Disable and hide the size column
40         $size_header.hide();
41         $size_inputs.each(function () {
42             $(this)
43                 .prop('disabled', true)
44                 .parent('td').hide();
45         });
47         // Disable and hide the columns of the index other than the first one
48         var initial = true;
49         $column_inputs.each(function () {
50             $column_input = $(this);
51             if (! initial) {
52                 $column_input
53                     .prop('disabled', true)
54                     .parent('td').hide();
55             } else {
56                 initial = false;
57             }
58         });
60         // Hide controllers to add more columns
61         $add_more.hide();
62     } else {
63         // Enable and show the size column
64         $size_header.show();
65         $size_inputs.each(function () {
66             $(this)
67                 .prop('disabled', false)
68                 .parent('td').show();
69         });
71         // Enable and show the columns of the index
72         $column_inputs.each(function () {
73             $(this)
74                 .prop('disabled', false)
75                 .parent('td').show();
76         });
78         // Show controllers to add more columns
79         $add_more.show();
80     }
83 /**
84  * Sets current index information into form parameters.
85  *
86  * @param array  source_array Array containing index columns
87  * @param string index_type   Type of index
88  *
89  * @return void
90  */
91 function PMA_setIndexFormParameters(source_array, index_type)
93     if (index_type == 'index') {
94         $('input[name="indexes"]').val(JSON.stringify(source_array));
95     } else {
96         $('input[name="' + index_type + '_indexes"]').val(JSON.stringify(source_array));
97     }
101  * Removes a column from an Index.
103  * @param string col_index Index of column in form
105  * @return void
106  */
107 function PMA_removeColumnFromIndex(col_index)
109     // Get previous index details.
110     var previous_index = $('select[name="field_key[' + col_index + ']"]')
111         .attr('data-index');
112     if (previous_index.length) {
113         previous_index = previous_index.split(',');
114         switch (previous_index[0].toLowerCase()) {
115         case 'primary':
116             source_array =  primary_indexes;
117             break;
118         case 'unique':
119             source_array = unique_indexes;
120             break;
121         case 'index':
122             source_array = indexes;
123             break;
124         case 'fulltext':
125             source_array = fulltext_indexes;
126             break;
127         default:
128             return;
129         }
131         // Remove column from index array.
132         var source_length = source_array[previous_index[1]].columns.length;
133         for (var i=0; i<source_length; i++) {
134             if (source_array[previous_index[1]].columns[i].col_index == col_index) {
135                 source_array[previous_index[1]].columns.splice(i, 1);
136             }
137         }
139         // Remove index completely if no columns left.
140         if (source_array[previous_index[1]].columns.length === 0) {
141             source_array.splice(previous_index[1], 1);
142         }
144         // Update current index details.
145         $('select[name="field_key[' + col_index + ']"]').attr('data-index', '');
146         // Update form index parameters.
147         PMA_setIndexFormParameters(source_array, previous_index[0].toLowerCase());
148     }
152  * Adds a column to an Index.
154  * @param array  source_array Array holding corresponding indexes
155  * @param string array_index  Index of an INDEX in array
156  * @param string index_type   Type of Index
157  * @param string col_index    Index of column on form
159  * @return void
160  */
161 function PMA_addColumnToIndex(source_array, array_index, index_type, col_index)
163     // Remove column from other indexes (if any).
164     PMA_removeColumnFromIndex(col_index);
165     var index_name = $('input[name="index[Key_name]"]').val();
166     var index_comment = $('input[name="index[Index_comment]"]').val();
167     var columns = [];
168     $('#index_columns tbody').find('tr').each(function () {
169         // Get columns in particular order.
170         var col_index = $(this).find('select[name="index[columns][names][]"]').val();
171         var size = $(this).find('input[name="index[columns][sub_parts][]"]').val();
172         columns.push({
173             'col_index': col_index,
174             'size': size
175         });
176     });
178     // Update or create an index.
179     source_array[array_index] = {
180         'Key_name': index_name,
181         'Index_comment': index_comment,
182         'Index_type': index_type.toUpperCase(),
183         'columns': columns
184     };
186     // Update index details on form.
187     $('select[name="field_key[' + col_index + ']"]')
188         .attr('data-index', index_type + ',' + array_index);
189     PMA_setIndexFormParameters(source_array, index_type.toLowerCase());
193  * Get choices list for a column to create a composite index with.
195  * @param string index_type   Type of index
196  * @param array  source_array Array hodling columns for particular index
198  * @return jQuery Object
199  */
200 function PMA_getCompositeIndexList(source_array, col_index)
202     // Remove any previous list.
203     if ($('#composite_index_list').length) {
204         $('#composite_index_list').remove();
205     }
207     // Html list.
208     var $composite_index_list = $(
209         '<ul id="composite_index_list">' +
210         '<div>' + PMA_messages.strCompositeWith + '</div>' +
211         '</ul>'
212     );
214     // Add each column to list available for composite index.
215     var source_length = source_array.length;
216     var already_present = false;
217     for (var i=0; i<source_length; i++) {
218         var sub_array_len = source_array[i].columns.length;
219         var column_names = [];
220         for (var j=0; j<sub_array_len; j++) {
221             column_names.push(
222                 $('input[name="field_name[' + source_array[i].columns[j].col_index + ']"]').val()
223             );
225             if (col_index == source_array[i].columns[j].col_index) {
226                 already_present = true;
227             }
228         }
230         $composite_index_list.append(
231             '<li>' +
232             '<input type="radio" name="composite_with" ' +
233             (already_present ? 'checked="checked"' : '') +
234             ' id="composite_index_' + i + '" value="' + i + '">' +
235             '<label for="composite_index_' + i + '">' + column_names.join(', ') +
236             '</lablel>' +
237             '</li>'
238         );
239     }
241     return $composite_index_list;
245  * Shows 'Add Index' dialog.
247  * @param array  source_array   Array holding particluar index
248  * @param string array_index    Index of an INDEX in array
249  * @param array  target_columns Columns for an INDEX
250  * @param string col_index      Index of column on form
251  * @param object index          Index detail object
253  * @return void
254  */
255 function PMA_showAddIndexDialog(source_array, array_index, target_columns, col_index, index)
257     // Prepare post-data.
258     var $table = $('input[name="table"]');
259     var table = $table.length > 0 ? $table.val() : '';
260     var post_data = {
261         token: $('input[name="token"]').val(),
262         server:  $('input[name="server"]').val(),
263         db: $('input[name="db"]').val(),
264         table: table,
265         ajax_request: 1,
266         create_edit_table: 1,
267         index: index
268     };
270     var columns = {};
271     for (var i=0; i<target_columns.length; i++) {
272         var column_name = $('input[name="field_name[' + target_columns[i] + ']"]').val();
273         var column_type = $('select[name="field_type[' + target_columns[i] + ']"]').val().toLowerCase();
274         columns[column_name] = [column_type, target_columns[i]];
275     }
276     post_data.columns = JSON.stringify(columns);
278     button_options = {};
279     button_options[PMA_messages.strGo] = function () {
280         var is_missing_value = false;
281         $('select[name="index[columns][names][]"]').each(function () {
282             if ($(this).val() === '') {
283                 is_missing_value = true;
284             }
285         });
287         if (! is_missing_value) {
288             PMA_addColumnToIndex(
289                 source_array,
290                 array_index,
291                 index.Index_type,
292                 col_index
293             );
294         } else {
295             PMA_ajaxShowMessage(
296                 '<div class="error"><img src="themes/dot.gif" title="" alt=""' +
297                 ' class="icon ic_s_error" /> ' + PMA_messages.strMissingColumn +
298                 ' </div>', false
299             );
301             return false;
302         }
304         $(this).dialog('close');
305     };
306     button_options[PMA_messages.strCancel] = function () {
307         // Handle state on 'Cancel'.
308         var $select_list = $('select[name="field_key[' + col_index + ']"]');
309         if (! $select_list.attr('data-index').length) {
310             $select_list.find('option[value*="none"]').attr('selected', 'selected');
311         } else {
312             var previous_index = $select_list.attr('data-index').split(',');
313             $select_list.find('option[value*="' + previous_index[0].toLowerCase() + '"]')
314                 .attr('selected', 'selected');
315         }
316         $(this).dialog('close');
317     };
318     var $msgbox = PMA_ajaxShowMessage();
319     $.post("tbl_indexes.php", post_data, function (data) {
320         if (data.success === false) {
321             //in the case of an error, show the error message returned.
322             PMA_ajaxShowMessage(data.error, false);
323         } else {
324             PMA_ajaxRemoveMessage($msgbox);
325             // Show dialog if the request was successful
326             $div = $('<div/>');
327             $div
328             .append(data.message)
329             .dialog({
330                 title: PMA_messages.strAddIndex,
331                 width: 450,
332                 minHeight: 250,
333                 open: function () {
334                     checkIndexName("index_frm");
335                     PMA_showHints($div);
336                     $('#index_columns td').each(function () {
337                         $(this).css("width", $(this).width() + 'px');
338                     });
339                     $('#index_columns tbody').sortable();
340                     // We dont need the slider at this moment.
341                     $(this).find('fieldset.tblFooters').remove();
342                 },
343                 modal: true,
344                 buttons: button_options,
345                 close: function () {
346                     $(this).remove();
347                 }
348             });
349         }
350     });
354  * Creates a advanced index type selection dialog.
356  * @param array  source_array Array holding a particular type of indexes
357  * @param string index_type   Type of index
358  * @param string col_index    Index of new column on form
360  * @return void
361  */
362 function PMA_indexTypeSelectionDialog(source_array, index_type, col_index)
364     var $single_column_radio = $('<input type="radio" id="single_column" name="index_type"' +
365         ' checked="checked">' +
366         '<label for="single_column">' + PMA_messages.strCreateSingleColumnIndex + '</label>');
367     var $composite_index_radio = $('<input type="radio" id="composite_index"' +
368         ' name="index_type">' +
369         '<label for="composite_index">' + PMA_messages.strCreateCompositeIndex + '</label>');
370     var $dialog_content = $('<fieldset id="advance_index_creator"></fieldset>');
371     $dialog_content.append('<legend>' + index_type.toUpperCase() + '</legend>');
374     // For UNIQUE/INDEX type, show choice for single-column and composite index.
375     $dialog_content.append($single_column_radio);
376     $dialog_content.append($composite_index_radio);
378     var button_options = {};
379     // 'OK' operation.
380     button_options[PMA_messages.strGo] = function () {
381         if ($('#single_column').is(':checked')) {
382             var index = {
383                 'Key_name': (index_type == 'primary' ? 'PRIMARY' : ''),
384                 'Index_type': index_type.toUpperCase()
385             };
386             PMA_showAddIndexDialog(source_array, (source_array.length), [col_index], col_index, index);
387         }
389         if ($('#composite_index').is(':checked')) {
390             if ($('input[name="composite_with"]').length !== 0 && $('input[name="composite_with"]:checked').length === 0
391             ) {
392                 PMA_ajaxShowMessage(
393                     '<div class="error"><img src="themes/dot.gif" title=""' +
394                     ' alt="" class="icon ic_s_error" /> ' +
395                     PMA_messages.strFormEmpty +
396                     ' </div>',
397                     false
398                 );
399                 return false;
400             }
402             var array_index = $('input[name="composite_with"]:checked').val();
403             var source_length = source_array[array_index].columns.length;
404             var target_columns = [];
405             for (var i=0; i<source_length; i++) {
406                 target_columns.push(source_array[array_index].columns[i].col_index);
407             }
408             target_columns.push(col_index);
410             PMA_showAddIndexDialog(source_array, array_index, target_columns, col_index,
411              source_array[array_index]);
412         }
414         $(this).remove();
415     };
416     button_options[PMA_messages.strCancel] = function () {
417         // Handle state on 'Cancel'.
418         var $select_list = $('select[name="field_key[' + col_index + ']"]');
419         if (! $select_list.attr('data-index').length) {
420             $select_list.find('option[value*="none"]').attr('selected', 'selected');
421         } else {
422             var previous_index = $select_list.attr('data-index').split(',');
423             $select_list.find('option[value*="' + previous_index[0].toLowerCase() + '"]')
424                 .attr('selected', 'selected');
425         }
426         $(this).remove();
427     };
428     var $dialog = $('<div/>').append($dialog_content).dialog({
429         minWidth: 525,
430         minHeight: 200,
431         modal: true,
432         title: PMA_messages.strAddIndex,
433         resizable: false,
434         buttons: button_options,
435         open: function () {
436             $('#composite_index').on('change', function () {
437                 if ($(this).is(':checked')) {
438                     $dialog_content.append(PMA_getCompositeIndexList(source_array, col_index));
439                 }
440             });
441             $('#single_column').on('change', function () {
442                 if ($(this).is(':checked')) {
443                     if ($('#composite_index_list').length) {
444                         $('#composite_index_list').remove();
445                     }
446                 }
447             });
448         },
449         close: function () {
450             $('#composite_index').off('change');
451             $('#single_column').off('change');
452             $(this).remove();
453         }
454     });
458  * Unbind all event handlers before tearing down a page
459  */
460 AJAX.registerTeardown('indexes.js', function () {
461     $('#select_index_type').die('change');
462     $('a.drop_primary_key_index_anchor.ajax').die('click');
463     $("#table_index tbody tr td.edit_index.ajax, #indexes .add_index.ajax").die('click');
464     $('#index_frm input[type=submit]').die('click');
465     $('body').off('change', 'select[name*="field_key"]');
469  * @description <p>Ajax scripts for table index page</p>
471  * Actions ajaxified here:
472  * <ul>
473  * <li>Showing/hiding inputs depending on the index type chosen</li>
474  * <li>create/edit/drop indexes</li>
475  * </ul>
476  */
477 AJAX.registerOnload('indexes.js', function () {
478     // Re-initialize variables.
479     primary_indexes = [];
480     unique_indexes = [];
481     indexes = [];
482     fulltext_indexes = [];
484     checkIndexType();
485     checkIndexName("index_frm");
486     $('#select_index_type').live('change', function (event) {
487         event.preventDefault();
488         checkIndexType();
489         checkIndexName("index_frm");
490     });
492     /**
493      * Ajax Event handler for 'Drop Index'
494      */
495     $('a.drop_primary_key_index_anchor.ajax').live('click', function (event) {
496         event.preventDefault();
497         var $anchor = $(this);
498         /**
499          * @var $curr_row    Object containing reference to the current field's row
500          */
501         var $curr_row = $anchor.parents('tr');
502         /** @var    Number of columns in the key */
503         var rows = $anchor.parents('td').attr('rowspan') || 1;
504         /** @var    Rows that should be hidden */
505         var $rows_to_hide = $curr_row;
506         for (var i = 1, $last_row = $curr_row.next(); i < rows; i++, $last_row = $last_row.next()) {
507             $rows_to_hide = $rows_to_hide.add($last_row);
508         }
510         var question = escapeHtml(
511             $curr_row.children('td')
512                 .children('.drop_primary_key_index_msg')
513                 .val()
514         );
516         $anchor.PMA_confirm(question, $anchor.attr('href'), function (url) {
517             var $msg = PMA_ajaxShowMessage(PMA_messages.strDroppingPrimaryKeyIndex, false);
518             $.get(url, {'is_js_confirmed': 1, 'ajax_request': true}, function (data) {
519                 if (typeof data !== 'undefined' && data.success === true) {
520                     PMA_ajaxRemoveMessage($msg);
521                     var $table_ref = $rows_to_hide.closest('table');
522                     if ($rows_to_hide.length == $table_ref.find('tbody > tr').length) {
523                         // We are about to remove all rows from the table
524                         $table_ref.hide('medium', function () {
525                             $('div.no_indexes_defined').show('medium');
526                             $rows_to_hide.remove();
527                         });
528                         $table_ref.siblings('div.notice').hide('medium');
529                     } else {
530                         // We are removing some of the rows only
531                         toggleRowColors($rows_to_hide.last().next());
532                         $rows_to_hide.hide("medium", function () {
533                             $(this).remove();
534                         });
535                     }
536                     if ($('#result_query').length) {
537                         $('#result_query').remove();
538                     }
539                     if (data.sql_query) {
540                         $('<div id="result_query"></div>')
541                             .html(data.sql_query)
542                             .prependTo('#page_content');
543                         PMA_highlightSQL($('#page_content'));
544                     }
545                     PMA_commonActions.refreshMain(false, function () {
546                         $("a.ajax[href^=#indexes]").click();
547                     });
548                     PMA_reloadNavigation();
549                 } else {
550                     PMA_ajaxShowMessage(PMA_messages.strErrorProcessingRequest + " : " + data.error, false);
551                 }
552             }); // end $.get()
553         }); // end $.PMA_confirm()
554     }); //end Drop Primary Key/Index
556     /**
557      *Ajax event handler for index edit
558     **/
559     $("#table_index tbody tr td.edit_index.ajax, #indexes .add_index.ajax").live('click', function (event) {
560         event.preventDefault();
561         var url, title;
562         if ($(this).find("a").length === 0) {
563             // Add index
564             var valid = checkFormElementInRange(
565                 $(this).closest('form')[0],
566                 'added_fields',
567                 'Column count has to be larger than zero.'
568             );
569             if (! valid) {
570                 return;
571             }
572             url = $(this).closest('form').serialize();
573             title = PMA_messages.strAddIndex;
574         } else {
575             // Edit index
576             url = $(this).find("a").attr("href");
577             if (url.substring(0, 16) == "tbl_indexes.php?") {
578                 url = url.substring(16, url.length);
579             }
580             title = PMA_messages.strEditIndex;
581         }
582         url += "&ajax_request=true";
583         indexEditorDialog(url, title, function () {
584             // refresh the page using ajax
585             PMA_commonActions.refreshMain(false, function () {
586                 $("a.ajax[href^=#indexes]").click();
587             });
588         });
589     });
591     /**
592      * Ajax event handler for advanced index creation during table creation
593      * and column addition.
594      */
595     $('body').on('change', 'select[name*="field_key"]', function () {
596         // Index of column on Table edit and create page.
597         var col_index = /\d/.exec($(this).attr('name'));
598         col_index = col_index[0];
599         // Type of selected index.
600         var index_type = /[a-z]+/.exec($(this).val());
601         index_type = index_type[0];
602         // Array containing corresponding indexes.
603         var source_array = null;
605         if (index_type == 'none') {
606             PMA_removeColumnFromIndex(col_index);
607             return false;
608         }
610         // Select a source array.
611         switch (index_type) {
612         case 'primary':
613             source_array =  primary_indexes;
614             break;
615         case 'unique':
616             source_array = unique_indexes;
617             break;
618         case 'index':
619             source_array = indexes;
620             break;
621         case 'fulltext':
622             source_array = fulltext_indexes;
623             break;
624         }
626         if (source_array.length === 0) {
627             var index = {
628                 'Key_name': (index_type == 'primary' ? 'PRIMARY' : ''),
629                 'Index_type': index_type.toUpperCase()
630             };
631             PMA_showAddIndexDialog(source_array, 0, [col_index], col_index, index);
632         } else {
633             if (index_type == 'primary') {
634                 var array_index = 0;
635                 var source_length = source_array[array_index].columns.length;
636                 var target_columns = [];
637                 for (var i=0; i<source_length; i++) {
638                     target_columns.push(source_array[array_index].columns[i].col_index);
639                 }
640                 target_columns.push(col_index);
642                 PMA_showAddIndexDialog(source_array, array_index, target_columns, col_index,
643                  source_array[array_index]);
644             } else {
645                 // If there are multiple columns selected for an index, show advanced dialog.
646                 PMA_indexTypeSelectionDialog(source_array, index_type, col_index);
647             }
648         }
649     });