Translated using Weblate (French)
[phpmyadmin.git] / js / tbl_structure.js
blobb8b8f68e1d9f169dd57ae6f3c87aea5adbe73d76
1 /* vim: set expandtab sw=4 ts=4 sts=4: */
2 /**
3  * @fileoverview    functions used on the table structure page
4  * @name            Table Structure
5  *
6  * @requires    jQuery
7  * @requires    jQueryUI
8  * @required    js/functions.js
9  */
11 /**
12  * AJAX scripts for tbl_structure.php
13  *
14  * Actions ajaxified here:
15  * Drop Column
16  * Add Primary Key
17  * Drop Primary Key/Index
18  *
19  */
21 /**
22  * This function returns the horizontal space available for the menu in pixels.
23  * To calculate this value we start we the width of the main panel, then we
24  * substract the margin of the page content, then we substract any cellspacing
25  * that the table may have (original theme only) and finally we substract the
26  * width of all columns of the table except for the last one (which is where
27  * the menu will go). What we should end up with is the distance between the
28  * start of the last column on the table and the edge of the page, again this
29  * is the space available for the menu.
30  *
31  * In the case where the table cell where the menu will be displayed is already
32  * off-screen (the table is wider than the page), a negative value will be returned,
33  * but this will be treated as a zero by the menuResizer plugin.
34  *
35  * @return int
36  */
37 function PMA_tbl_structure_menu_resizer_callback() {
38     var pagewidth = $('body').width();
39     var $page = $('#page_content');
40     pagewidth -= $page.outerWidth(true) - $page.outerWidth();
41     var columnsWidth = 0;
42     var $columns = $('#tablestructure').find('tr:eq(1)').find('td,th');
43     $columns.not(':last').each(function () {
44         columnsWidth += $(this).outerWidth(true);
45     });
46     var totalCellSpacing = $('#tablestructure').width();
47     $columns.each(function () {
48         totalCellSpacing -= $(this).outerWidth(true);
49     });
50     return pagewidth - columnsWidth - totalCellSpacing - 15; // 15px extra margin
53 /**
54  * Reload fields table
55  */
56 function reloadFieldForm() {
57     $.post($("#fieldsForm").attr('action'), $("#fieldsForm").serialize() + "&ajax_request=true", function (form_data) {
58         var $temp_div = $("<div id='temp_div'><div>").append(form_data.message);
59         $("#fieldsForm").replaceWith($temp_div.find("#fieldsForm"));
60         $("#addColumns").replaceWith($temp_div.find("#addColumns"));
61         $('#move_columns_dialog ul').replaceWith($temp_div.find("#move_columns_dialog ul"));
62         $("#moveColumns").removeClass("move-active");
63         /* reinitialise the more options in table */
64         if ($('#fieldsForm').hasClass('HideStructureActions')) {
65             $('#fieldsForm ul.table-structure-actions').menuResizer(PMA_tbl_structure_menu_resizer_callback);
66         }
67     });
68     $('#page_content').show();
71 function checkFirst() {
72     if ($("select[name=after_field] option:selected").data('pos') === 'first') {
73         $("input[name=field_where]").val('first');
74     } else {
75         $("input[name=field_where]").val('after');
76     }
78 /**
79  * Unbind all event handlers before tearing down a page
80  */
81 AJAX.registerTeardown('tbl_structure.js', function () {
82     $(document).off('click', "a.drop_column_anchor.ajax");
83     $(document).off('click', "a.add_key.ajax");
84     $(document).off('click', "#move_columns_anchor");
85     $(document).off('click', "#printView");
86     $(document).off('submit', ".append_fields_form.ajax");
87     $('body').off('click', '#fieldsForm.ajax button[name="submit_mult"], #fieldsForm.ajax input[name="submit_mult"]');
88 });
90 AJAX.registerOnload('tbl_structure.js', function () {
92     // Re-initialize variables.
93     primary_indexes = [];
94     unique_indexes = [];
95     indexes = [];
96     fulltext_indexes = [];
97     spatial_indexes = [];
99     /**
100      *Ajax action for submitting the "Column Change" and "Add Column" form
101      */
102     $(".append_fields_form.ajax").off();
103     $(document).on('submit', ".append_fields_form.ajax", function (event) {
104         event.preventDefault();
105         /**
106          * @var    the_form    object referring to the export form
107          */
108         var $form = $(this);
109         var field_cnt = $form.find('input[name=orig_num_fields]').val();
112         function submitForm(){
113             $msg = PMA_ajaxShowMessage(PMA_messages.strProcessingRequest);
114             $.post($form.attr('action'), $form.serialize() + '&do_save_data=1', function (data) {
115                 if ($(".sqlqueryresults").length !== 0) {
116                     $(".sqlqueryresults").remove();
117                 } else if ($(".error:not(.tab)").length !== 0) {
118                     $(".error:not(.tab)").remove();
119                 }
120                 if (typeof data.success != 'undefined' && data.success === true) {
121                     $("#page_content")
122                         .empty()
123                         .append(data.message)
124                         .show();
125                     PMA_highlightSQL($('#page_content'));
126                     $(".result_query .notice").remove();
127                     reloadFieldForm();
128                     $form.remove();
129                     PMA_ajaxRemoveMessage($msg);
130                     PMA_init_slider();
131                     PMA_reloadNavigation();
132                 } else {
133                     PMA_ajaxShowMessage(data.error, false);
134                 }
135             }); // end $.post()
136         }
138         function checkIfConfirmRequired($form, $field_cnt) {
139             var i = 0, id, elm, val, name_orig, elm_orig, val_orig;
140             var checkRequired = false;
141             for (i = 0; i < field_cnt; i++) {
142                 id = "#field_" + i + "_5";
143                 elm = $(id);
144                 val = elm.val();
146                 name_orig = "input[name=field_collation_orig\\[" + i + "\\]]";
147                 elm_orig = $form.find(name_orig);
148                 val_orig = elm_orig.val();
150                 if (val && val_orig && val !== val_orig){
151                     checkRequired = true;
152                     break;
153                 }
154             }
155             return checkRequired;
156         }
158         /*
159          * First validate the form; if there is a problem, avoid submitting it
160          *
161          * checkTableEditForm() needs a pure element and not a jQuery object,
162          * this is why we pass $form[0] as a parameter (the jQuery object
163          * is actually an array of DOM elements)
164          */
165         if (checkTableEditForm($form[0], field_cnt)) {
166             // OK, form passed validation step
168             PMA_prepareForAjaxRequest($form);
169             if (PMA_checkReservedWordColumns($form)) {
170                 //User wants to submit the form
172                 // If Collation is changed, Warn and Confirm
173                 if (checkIfConfirmRequired($form, field_cnt)){
174                     var question = sprintf(
175                         PMA_messages.strChangeColumnCollation, 'http://wiki.phpmyadmin.net/pma/Garbled_data'
176                     );
177                     $form.PMA_confirm(question, $form.attr('action'), function (url) {
178                         submitForm();
179                     });
180                 } else {
181                     submitForm();
182                 }
183             }
184         }
185     }); // end change table button "do_save_data"
187     /**
188      * Attach Event Handler for 'Drop Column'
189      */
190     $(document).on('click', "a.drop_column_anchor.ajax", function (event) {
191         event.preventDefault();
192         /**
193          * @var curr_table_name String containing the name of the current table
194          */
195         var curr_table_name = $(this).closest('form').find('input[name=table]').val();
196         /**
197          * @var curr_row    Object reference to the currently selected row (i.e. field in the table)
198          */
199         var $curr_row = $(this).parents('tr');
200         /**
201          * @var curr_column_name    String containing name of the field referred to by {@link curr_row}
202          */
203         var curr_column_name = $curr_row.children('th').children('label').text();
204         curr_column_name = escapeHtml(curr_column_name);
205         /**
206          * @var $after_field_item    Corresponding entry in the 'After' field.
207          */
208         var $after_field_item = $("select[name='after_field'] option[value='" + curr_column_name + "']");
209         /**
210          * @var question    String containing the question to be asked for confirmation
211          */
212         var question = PMA_sprintf(PMA_messages.strDoYouReally, 'ALTER TABLE `' + escapeHtml(curr_table_name) + '` DROP `' + escapeHtml(curr_column_name) + '`;');
213         $(this).PMA_confirm(question, $(this).attr('href'), function (url) {
214             var $msg = PMA_ajaxShowMessage(PMA_messages.strDroppingColumn, false);
215             $.get(url, {'is_js_confirmed' : 1, 'ajax_request' : true, 'ajax_page_request' : true}, function (data) {
216                 if (typeof data !== 'undefined' && data.success === true) {
217                     PMA_ajaxRemoveMessage($msg);
218                     if ($('.result_query').length) {
219                         $('.result_query').remove();
220                     }
221                     if (data.sql_query) {
222                         $('<div class="result_query"></div>')
223                             .html(data.sql_query)
224                             .prependTo('#structure_content');
225                         PMA_highlightSQL($('#page_content'));
226                     }
227                     toggleRowColors($curr_row.next());
228                     // Adjust the row numbers
229                     for (var $row = $curr_row.next(); $row.length > 0; $row = $row.next()) {
230                         var new_val = parseInt($row.find('td:nth-child(2)').text(), 10) - 1;
231                         $row.find('td:nth-child(2)').text(new_val);
232                     }
233                     $after_field_item.remove();
234                     $curr_row.hide("medium").remove();
235                     //by default select the last option to add new column (in case last column is dropped)
236                     $("select[name=after_field] option:last").attr("selected","selected");
237                     //refresh table stats
238                     if (data.tableStat) {
239                         $('#tablestatistics').html(data.tableStat);
240                     }
241                     // refresh the list of indexes (comes from sql.php)
242                     $('.index_info').replaceWith(data.indexes_list);
243                     PMA_reloadNavigation();
244                 } else {
245                     PMA_ajaxShowMessage(PMA_messages.strErrorProcessingRequest + " : " + data.error, false);
246                 }
247             }); // end $.get()
248         }); // end $.PMA_confirm()
249     }); //end of Drop Column Anchor action
251     /**
252      * Attach Event Handler for 'Print View'
253      */
254     $(document).on('click', "#printView", function (event) {
255         event.preventDefault();
257         // Print the page
258         printPage();
259     }); //end of Print View action
261     /**
262      * Ajax Event handler for adding keys
263      */
264     $(document).on('click', "a.add_key.ajax", function (event) {
265         event.preventDefault();
267         var $this = $(this);
268         var curr_table_name = $this.closest('form').find('input[name=table]').val();
269         var curr_column_name = $this.parents('tr').children('th').children('label').text();
271         var add_clause = '';
272         if ($this.is('.add_primary_key_anchor')) {
273             add_clause = 'ADD PRIMARY KEY';
274         } else if ($this.is('.add_index_anchor')) {
275             add_clause = 'ADD INDEX';
276         } else if ($this.is('.add_unique_anchor')) {
277             add_clause = 'ADD UNIQUE';
278         } else if ($this.is('.add_spatial_anchor')) {
279             add_clause = 'ADD SPATIAL';
280         } else if ($this.is('.add_fulltext_anchor')) {
281             add_clause = 'ADD FULLTEXT';
282         }
283         var question = PMA_sprintf(PMA_messages.strDoYouReally, 'ALTER TABLE `' +
284                 escapeHtml(curr_table_name) + '` ' + add_clause + '(`' + escapeHtml(curr_column_name) + '`);');
286         $(this).PMA_confirm(question, $(this).attr('href'), function (url) {
287             PMA_ajaxShowMessage();
288             AJAX.source = $this;
289             $.get(url, {'ajax_request' : true, 'ajax_page_request' : true}, AJAX.responseHandler);
290         }); // end $.PMA_confirm()
291     }); //end Add key
293     /**
294      * Inline move columns
295     **/
296     $(document).on('click', "#move_columns_anchor", function (e) {
297         e.preventDefault();
299         if ($(this).hasClass("move-active")) {
300             return;
301         }
303         /**
304          * @var    button_options  Object that stores the options passed to jQueryUI
305          *                          dialog
306          */
307         var button_options = {};
309         button_options[PMA_messages.strGo] = function (event) {
310             event.preventDefault();
311             var $msgbox = PMA_ajaxShowMessage();
312             var $this = $(this);
313             var $form = $this.find("form");
314             var serialized = $form.serialize();
316             // check if any columns were moved at all
317             if (serialized == $form.data("serialized-unmoved")) {
318                 PMA_ajaxRemoveMessage($msgbox);
319                 $this.dialog('close');
320                 return;
321             }
323             $.post($form.prop("action"), serialized + "&ajax_request=true", function (data) {
324                 if (data.success === false) {
325                     PMA_ajaxRemoveMessage($msgbox);
326                     $this
327                     .clone()
328                     .html(data.error)
329                     .dialog({
330                         title: $(this).prop("title"),
331                         height: 230,
332                         width: 900,
333                         modal: true,
334                         buttons: button_options_error
335                     }); // end dialog options
336                 } else {
337                     if ($('#fieldsForm').hasClass('HideStructureActions')) {
338                         $('#fieldsForm ul.table-structure-actions').menuResizer('destroy');
339                     }
340                     // sort the fields table
341                     var $fields_table = $("table#tablestructure tbody");
342                     // remove all existing rows and remember them
343                     var $rows = $fields_table.find("tr").remove();
344                     // loop through the correct order
345                     for (var i in data.columns) {
346                         var the_column = data.columns[i];
347                         var $the_row = $rows
348                             .find("input:checkbox[value=" + the_column + "]")
349                             .closest("tr");
350                         // append the row for this column to the table
351                         $fields_table.append($the_row);
352                     }
353                     var $firstrow = $fields_table.find("tr").eq(0);
354                     // Adjust the row numbers and colors
355                     for (var $row = $firstrow; $row.length > 0; $row = $row.next()) {
356                         $row
357                         .find('td:nth-child(2)')
358                         .text($row.index() + 1)
359                         .end()
360                         .removeClass("odd even")
361                         .addClass($row.index() % 2 === 0 ? "odd" : "even");
362                     }
363                     PMA_ajaxShowMessage(data.message);
364                     $this.dialog('close');
365                     if ($('#fieldsForm').hasClass('HideStructureActions')) {
366                         $('#fieldsForm ul.table-structure-actions').menuResizer(PMA_tbl_structure_menu_resizer_callback);
367                     }
368                 }
369             });
370         };
371         button_options[PMA_messages.strCancel] = function () {
372             $(this).dialog('close');
373         };
375         var button_options_error = {};
376         button_options_error[PMA_messages.strOK] = function () {
377             $(this).dialog('close').remove();
378         };
380         var columns = [];
382         $("#tablestructure tbody tr").each(function () {
383             var col_name = $(this).find("input:checkbox").eq(0).val();
384             var hidden_input = $("<input/>")
385                 .prop({
386                     name: "move_columns[]",
387                     type: "hidden"
388                 })
389                 .val(col_name);
390             columns[columns.length] = $("<li/>")
391                 .addClass("placeholderDrag")
392                 .text(col_name)
393                 .append(hidden_input);
394         });
396         var col_list = $("#move_columns_dialog ul")
397             .find("li").remove().end();
398         for (var i in columns) {
399             col_list.append(columns[i]);
400         }
401         col_list.sortable({
402             axis: 'y',
403             containment: $("#move_columns_dialog div"),
404             tolerance: 'pointer'
405         }).disableSelection();
406         var $form = $("#move_columns_dialog form");
407         $form.data("serialized-unmoved", $form.serialize());
409         $("#move_columns_dialog").dialog({
410             modal: true,
411             buttons: button_options,
412             open: function () {
413                 if ($('#move_columns_dialog').parents('.ui-dialog').height() > $(window).height()) {
414                     $('#move_columns_dialog').dialog("option", "height", $(window).height());
415                 }
416             },
417             beforeClose: function () {
418                 $("#move_columns_anchor").removeClass("move-active");
419             }
420         });
421     });
423     /**
424      * Handles multi submits in table structure page such as change, browse, drop, primary etc.
425      */
426     $('body').on('click', '#fieldsForm.ajax button[name="submit_mult"], #fieldsForm.ajax input[name="submit_mult"]', function (e) {
427         e.preventDefault();
428         var $button = $(this);
429         var $form = $button.parents('form');
430         var submitData = $form.serialize() + '&ajax_request=true&ajax_page_request=true&submit_mult=' + $button.val();
431         PMA_ajaxShowMessage();
432         AJAX.source = $form;
433         $.post($form.attr('action'), submitData, AJAX.responseHandler);
434     });
437 /** Handler for "More" dropdown in structure table rows */
438 AJAX.registerOnload('tbl_structure.js', function () {
439     if ($('#fieldsForm').hasClass('HideStructureActions')) {
440         $('#fieldsForm ul.table-structure-actions').menuResizer(PMA_tbl_structure_menu_resizer_callback);
441     } else {
442         $('.table-structure-actions').width(function () {
443             var width = 5;
444             $(this).find('li').each(function () {
445                 width += $(this).outerWidth(true);
446             });
447             return width;
448         });
449     }
451 AJAX.registerTeardown('tbl_structure.js', function () {
452     if ($('#fieldsForm').hasClass('HideStructureActions')) {
453         $('#fieldsForm ul.table-structure-actions').menuResizer('destroy');
454     }
456 $(function () {
457     $(window).resize($.throttle(function () {
458         if ($('#fieldsForm').length && $('#fieldsForm').hasClass('HideStructureActions')) {
459             $('#fieldsForm ul.table-structure-actions').menuResizer('resize');
460         }
461     }));