1 /* vim: set expandtab sw=4 ts=4 sts=4: */
3 * @fileoverview functions used on the table structure page
4 * @name Table Structure
8 * @required js/functions.js
12 * AJAX scripts for tbl_structure.php
14 * Actions ajaxified here:
17 * Drop Primary Key/Index
24 function reloadFieldForm () {
25 $.post($('#fieldsForm').attr('action'), $('#fieldsForm').serialize() + PMA_commonParams.get('arg_separator') + 'ajax_request=true', function (form_data) {
26 var $temp_div = $('<div id=\'temp_div\'><div>').append(form_data.message);
27 $('#fieldsForm').replaceWith($temp_div.find('#fieldsForm'));
28 $('#addColumns').replaceWith($temp_div.find('#addColumns'));
29 $('#move_columns_dialog').find('ul').replaceWith($temp_div.find('#move_columns_dialog ul'));
30 $('#moveColumns').removeClass('move-active');
32 $('#page_content').show();
35 function checkFirst () {
36 if ($('select[name=after_field] option:selected').data('pos') === 'first') {
37 $('input[name=field_where]').val('first');
39 $('input[name=field_where]').val('after');
43 * Unbind all event handlers before tearing down a page
45 AJAX.registerTeardown('tbl_structure.js', function () {
46 $(document).off('click', 'a.drop_column_anchor.ajax');
47 $(document).off('click', 'a.add_key.ajax');
48 $(document).off('click', '#move_columns_anchor');
49 $(document).off('click', '#printView');
50 $(document).off('submit', '.append_fields_form.ajax');
51 $('body').off('click', '#fieldsForm.ajax button[name="submit_mult"], #fieldsForm.ajax input[name="submit_mult"]');
52 $(document).off('click', 'a[name^=partition_action].ajax');
53 $(document).off('click', '#remove_partitioning.ajax');
56 AJAX.registerOnload('tbl_structure.js', function () {
57 // Re-initialize variables.
60 fulltext_indexes = [];
64 *Ajax action for submitting the "Column Change" and "Add Column" form
66 $('.append_fields_form.ajax').off();
67 $(document).on('submit', '.append_fields_form.ajax', function (event) {
68 event.preventDefault();
70 * @var the_form object referring to the export form
73 var field_cnt = $form.find('input[name=orig_num_fields]').val();
76 function submitForm () {
77 $msg = PMA_ajaxShowMessage(PMA_messages.strProcessingRequest);
78 $.post($form.attr('action'), $form.serialize() + PMA_commonParams.get('arg_separator') + 'do_save_data=1', function (data) {
79 if ($('.sqlqueryresults').length !== 0) {
80 $('.sqlqueryresults').remove();
81 } else if ($('.error:not(.tab)').length !== 0) {
82 $('.error:not(.tab)').remove();
84 if (typeof data.success !== 'undefined' && data.success === true) {
89 PMA_highlightSQL($('#page_content'));
90 $('.result_query .notice').remove();
93 PMA_ajaxRemoveMessage($msg);
95 PMA_reloadNavigation();
97 PMA_ajaxShowMessage(data.error, false);
102 function checkIfConfirmRequired ($form, $field_cnt) {
110 var checkRequired = false;
111 for (i = 0; i < field_cnt; i++) {
112 id = '#field_' + i + '_5';
116 name_orig = 'input[name=field_collation_orig\\[' + i + '\\]]';
117 elm_orig = $form.find(name_orig);
118 val_orig = elm_orig.val();
120 if (val && val_orig && val !== val_orig) {
121 checkRequired = true;
125 return checkRequired;
129 * First validate the form; if there is a problem, avoid submitting it
131 * checkTableEditForm() needs a pure element and not a jQuery object,
132 * this is why we pass $form[0] as a parameter (the jQuery object
133 * is actually an array of DOM elements)
135 if (checkTableEditForm($form[0], field_cnt)) {
136 // OK, form passed validation step
138 PMA_prepareForAjaxRequest($form);
139 if (PMA_checkReservedWordColumns($form)) {
140 // User wants to submit the form
142 // If Collation is changed, Warn and Confirm
143 if (checkIfConfirmRequired($form, field_cnt)) {
144 var question = sprintf(
145 PMA_messages.strChangeColumnCollation, 'https://wiki.phpmyadmin.net/pma/Garbled_data'
147 $form.PMA_confirm(question, $form.attr('action'), function (url) {
155 }); // end change table button "do_save_data"
158 * Attach Event Handler for 'Drop Column'
160 $(document).on('click', 'a.drop_column_anchor.ajax', function (event) {
161 event.preventDefault();
163 * @var curr_table_name String containing the name of the current table
165 var curr_table_name = $(this).closest('form').find('input[name=table]').val();
167 * @var curr_row Object reference to the currently selected row (i.e. field in the table)
169 var $curr_row = $(this).parents('tr');
171 * @var curr_column_name String containing name of the field referred to by {@link curr_row}
173 var curr_column_name = $curr_row.children('th').children('label').text().trim();
174 curr_column_name = escapeHtml(curr_column_name);
176 * @var $after_field_item Corresponding entry in the 'After' field.
178 var $after_field_item = $('select[name=\'after_field\'] option[value=\'' + curr_column_name + '\']');
180 * @var question String containing the question to be asked for confirmation
182 var question = PMA_sprintf(PMA_messages.strDoYouReally, 'ALTER TABLE `' + escapeHtml(curr_table_name) + '` DROP `' + escapeHtml(curr_column_name) + '`;');
183 var $this_anchor = $(this);
184 $this_anchor.PMA_confirm(question, $this_anchor.attr('href'), function (url) {
185 var $msg = PMA_ajaxShowMessage(PMA_messages.strDroppingColumn, false);
186 var params = getJSConfirmCommonParam(this, $this_anchor.getPostData());
187 params += PMA_commonParams.get('arg_separator') + 'ajax_page_request=1';
188 $.post(url, params, function (data) {
189 if (typeof data !== 'undefined' && data.success === true) {
190 PMA_ajaxRemoveMessage($msg);
191 if ($('.result_query').length) {
192 $('.result_query').remove();
194 if (data.sql_query) {
195 $('<div class="result_query"></div>')
196 .html(data.sql_query)
197 .prependTo('#structure_content');
198 PMA_highlightSQL($('#page_content'));
200 // Adjust the row numbers
201 for (var $row = $curr_row.next(); $row.length > 0; $row = $row.next()) {
202 var new_val = parseInt($row.find('td:nth-child(2)').text(), 10) - 1;
203 $row.find('td:nth-child(2)').text(new_val);
205 $after_field_item.remove();
206 $curr_row.hide('medium').remove();
208 // Remove the dropped column from select menu for 'after field'
209 $('select[name=after_field]').find(
210 '[value="' + curr_column_name + '"]'
213 // by default select the (new) last option to add new column
214 // (in case last column is dropped)
215 $('select[name=after_field] option:last').attr('selected','selected');
217 // refresh table stats
218 if (data.tableStat) {
219 $('#tablestatistics').html(data.tableStat);
221 // refresh the list of indexes (comes from sql.php)
222 $('.index_info').replaceWith(data.indexes_list);
223 PMA_reloadNavigation();
225 PMA_ajaxShowMessage(PMA_messages.strErrorProcessingRequest + ' : ' + data.error, false);
228 }); // end $.PMA_confirm()
229 }); // end of Drop Column Anchor action
232 * Attach Event Handler for 'Print' link
234 $(document).on('click', '#printView', function (event) {
235 event.preventDefault();
237 // Take to preview mode
239 }); // end of Print View action
242 * Ajax Event handler for adding keys
244 $(document).on('click', 'a.add_key.ajax', function (event) {
245 event.preventDefault();
248 var curr_table_name = $this.closest('form').find('input[name=table]').val();
249 var curr_column_name = $this.parents('tr').children('th').children('label').text().trim();
252 if ($this.is('.add_primary_key_anchor')) {
253 add_clause = 'ADD PRIMARY KEY';
254 } else if ($this.is('.add_index_anchor')) {
255 add_clause = 'ADD INDEX';
256 } else if ($this.is('.add_unique_anchor')) {
257 add_clause = 'ADD UNIQUE';
258 } else if ($this.is('.add_spatial_anchor')) {
259 add_clause = 'ADD SPATIAL';
260 } else if ($this.is('.add_fulltext_anchor')) {
261 add_clause = 'ADD FULLTEXT';
263 var question = PMA_sprintf(PMA_messages.strDoYouReally, 'ALTER TABLE `' +
264 escapeHtml(curr_table_name) + '` ' + add_clause + '(`' + escapeHtml(curr_column_name) + '`);');
266 var $this_anchor = $(this);
268 $this_anchor.PMA_confirm(question, $this_anchor.attr('href'), function (url) {
269 PMA_ajaxShowMessage();
272 var params = getJSConfirmCommonParam(this, $this_anchor.getPostData());
273 params += PMA_commonParams.get('arg_separator') + 'ajax_page_request=1';
274 $.post(url, params, AJAX.responseHandler);
275 }); // end $.PMA_confirm()
279 * Inline move columns
281 $(document).on('click', '#move_columns_anchor', function (e) {
284 if ($(this).hasClass('move-active')) {
289 * @var button_options Object that stores the options passed to jQueryUI
292 var button_options = {};
294 button_options[PMA_messages.strGo] = function (event) {
295 event.preventDefault();
296 var $msgbox = PMA_ajaxShowMessage();
298 var $form = $this.find('form');
299 var serialized = $form.serialize();
301 // check if any columns were moved at all
302 if (serialized === $form.data('serialized-unmoved')) {
303 PMA_ajaxRemoveMessage($msgbox);
304 $this.dialog('close');
308 $.post($form.prop('action'), serialized + PMA_commonParams.get('arg_separator') + 'ajax_request=true', function (data) {
309 if (data.success === false) {
310 PMA_ajaxRemoveMessage($msgbox);
315 title: $(this).prop('title'),
319 buttons: button_options_error
320 }); // end dialog options
322 // sort the fields table
323 var $fields_table = $('table#tablestructure tbody');
324 // remove all existing rows and remember them
325 var $rows = $fields_table.find('tr').remove();
326 // loop through the correct order
327 for (var i in data.columns) {
328 var the_column = data.columns[i];
330 .find('input:checkbox[value=\'' + the_column + '\']')
332 // append the row for this column to the table
333 $fields_table.append($the_row);
335 var $firstrow = $fields_table.find('tr').eq(0);
336 // Adjust the row numbers and colors
337 for (var $row = $firstrow; $row.length > 0; $row = $row.next()) {
339 .find('td:nth-child(2)')
340 .text($row.index() + 1)
342 .removeClass('odd even')
343 .addClass($row.index() % 2 === 0 ? 'odd' : 'even');
345 PMA_ajaxShowMessage(data.message);
346 $this.dialog('close');
350 button_options[PMA_messages.strCancel] = function () {
351 $(this).dialog('close');
354 var button_options_error = {};
355 button_options_error[PMA_messages.strOK] = function () {
356 $(this).dialog('close').remove();
361 $('#tablestructure').find('tbody tr').each(function () {
362 var col_name = $(this).find('input:checkbox').eq(0).val();
363 var hidden_input = $('<input/>')
365 name: 'move_columns[]',
369 columns[columns.length] = $('<li/>')
370 .addClass('placeholderDrag')
372 .append(hidden_input);
375 var col_list = $('#move_columns_dialog').find('ul')
376 .find('li').remove().end();
377 for (var i in columns) {
378 col_list.append(columns[i]);
382 containment: $('#move_columns_dialog').find('div'),
384 }).disableSelection();
385 var $form = $('#move_columns_dialog').find('form');
386 $form.data('serialized-unmoved', $form.serialize());
388 $('#move_columns_dialog').dialog({
390 buttons: button_options,
392 if ($('#move_columns_dialog').parents('.ui-dialog').height() > $(window).height()) {
393 $('#move_columns_dialog').dialog('option', 'height', $(window).height());
396 beforeClose: function () {
397 $('#move_columns_anchor').removeClass('move-active');
403 * Handles multi submits in table structure page such as change, browse, drop, primary etc.
405 $('body').on('click', '#fieldsForm.ajax button[name="submit_mult"], #fieldsForm.ajax input[name="submit_mult"]', function (e) {
407 var $button = $(this);
408 var $form = $button.parents('form');
409 var argsep = PMA_commonParams.get('arg_separator');
410 var submitData = $form.serialize() + argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true' + argsep + 'submit_mult=' + $button.val();
411 PMA_ajaxShowMessage();
413 $.post($form.attr('action'), submitData, AJAX.responseHandler);
417 * Handles clicks on Action links in partition table
419 $(document).on('click', 'a[name^=partition_action].ajax', function (e) {
423 function submitPartitionAction (url) {
424 var params = 'ajax_request=true&ajax_page_request=true&' + $link.getPostData();
425 PMA_ajaxShowMessage();
427 $.post(url, params, AJAX.responseHandler);
430 if ($link.is('#partition_action_DROP')) {
431 var question = PMA_messages.strDropPartitionWarning;
432 $link.PMA_confirm(question, $link.attr('href'), function (url) {
433 submitPartitionAction(url);
435 } else if ($link.is('#partition_action_TRUNCATE')) {
436 var question = PMA_messages.strTruncatePartitionWarning;
437 $link.PMA_confirm(question, $link.attr('href'), function (url) {
438 submitPartitionAction(url);
441 submitPartitionAction($link.attr('href'));
446 * Handles remove partitioning
448 $(document).on('click', '#remove_partitioning.ajax', function (e) {
451 var question = PMA_messages.strRemovePartitioningWarning;
452 $link.PMA_confirm(question, $link.attr('href'), function (url) {
453 var params = getJSConfirmCommonParam({
454 'ajax_request' : true,
455 'ajax_page_request' : true
456 }, $link.getPostData());
457 PMA_ajaxShowMessage();
459 $.post(url, params, AJAX.responseHandler);
463 $(document).on('change', 'select[name=after_field]', function () {
468 /** Handler for "More" dropdown in structure table rows */
469 AJAX.registerOnload('tbl_structure.js', function () {
470 var windowwidth = $(window).width();
471 if (windowwidth > 768) {
472 if (! $('#fieldsForm').hasClass('HideStructureActions')) {
473 $('.table-structure-actions').width(function () {
475 $(this).find('li').each(function () {
476 width += $(this).outerWidth(true);
483 $('.jsresponsive').css('max-width', (windowwidth - 35) + 'px');
484 var tableRows = $('.central_columns');
485 $.each(tableRows, function (index, item) {
486 if ($(item).hasClass('add_button')) {
487 $(item).click(function () {
488 $('input:checkbox').prop('checked', false);
489 $('#checkbox_row_' + (index + 1)).prop('checked', true);
490 $('button[value=add_to_central_columns]').click();
493 $(item).click(function () {
494 $('input:checkbox').prop('checked', false);
495 $('#checkbox_row_' + (index + 1)).prop('checked', true);
496 $('button[value=remove_from_central_columns]').click();