1 /* vim: set expandtab sw=4 ts=4 sts=4: */
3 * @fileoverview function used for index manipulation pages
4 * @name Table Structure
8 * @required js/functions.js
12 * Hides/shows the inputs and submits appropriately depending
13 * on whether the index type chosen is 'SPATIAL' or not.
15 function checkIndexType()
18 * @var Object Dropdown to select the index type.
20 $select_index_type = $('#select_index_type');
22 * @var Object Table header for the size column.
24 $size_header = $('#index_columns thead tr th:nth-child(2)');
26 * @var Object Inputs to specify the columns for the index.
28 $column_inputs = $('select[name="index[columns][names][]"]');
30 * @var Object Inputs to specify sizes for columns of the index.
32 $size_inputs = $('input[name="index[columns][sub_parts][]"]');
34 * @var Object Footer containg the controllers to add more columns
36 $add_more = $('#index_frm .tblFooters');
38 if ($select_index_type.val() == 'SPATIAL') {
39 // Disable and hide the size column
41 $size_inputs.each(function () {
43 .prop('disabled', true)
47 // Disable and hide the columns of the index other than the first one
49 $column_inputs.each(function () {
50 $column_input = $(this);
53 .prop('disabled', true)
60 // Hide controllers to add more columns
63 // Enable and show the size column
65 $size_inputs.each(function () {
67 .prop('disabled', false)
71 // Enable and show the columns of the index
72 $column_inputs.each(function () {
74 .prop('disabled', false)
78 // Show controllers to add more columns
84 * Sets current index information into form parameters.
86 * @param array source_array Array containing index columns
87 * @param string index_type Type of index
91 function PMA_setIndexFormParameters(source_array, index_type)
93 if (index_type == 'index') {
94 $('input[name="indexes"]').val(JSON.stringify(source_array));
96 $('input[name="' + index_type + '_indexes"]').val(JSON.stringify(source_array));
101 * Removes a column from an Index.
103 * @param string col_index Index of column in form
107 function PMA_removeColumnFromIndex(col_index)
109 // Get previous index details.
110 var previous_index = $('select[name="field_key[' + col_index + ']"]')
112 if (previous_index.length) {
113 previous_index = previous_index.split(',');
114 switch (previous_index[0].toLowerCase()) {
116 source_array = primary_indexes;
119 source_array = unique_indexes;
122 source_array = indexes;
125 source_array = fulltext_indexes;
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);
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);
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());
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
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();
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();
173 'col_index': col_index,
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(),
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
200 function PMA_getCompositeIndexList(source_array, col_index)
202 // Remove any previous list.
203 if ($('#composite_index_list').length) {
204 $('#composite_index_list').remove();
208 var $composite_index_list = $(
209 '<ul id="composite_index_list">' +
210 '<div>' + PMA_messages.strCompositeWith + '</div>' +
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++) {
222 $('input[name="field_name[' + source_array[i].columns[j].col_index + ']"]').val()
225 if (col_index == source_array[i].columns[j].col_index) {
226 already_present = true;
230 $composite_index_list.append(
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(', ') +
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
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() : '';
261 token: $('input[name="token"]').val(),
262 server: $('input[name="server"]').val(),
263 db: $('input[name="db"]').val(),
266 create_edit_table: 1,
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]];
276 post_data.columns = JSON.stringify(columns);
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;
287 if (! is_missing_value) {
288 PMA_addColumnToIndex(
296 '<div class="error"><img src="themes/dot.gif" title="" alt=""' +
297 ' class="icon ic_s_error" /> ' + PMA_messages.strMissingColumn +
304 $(this).dialog('close');
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');
312 var previous_index = $select_list.attr('data-index').split(',');
313 $select_list.find('option[value*="' + previous_index[0].toLowerCase() + '"]')
314 .attr('selected', 'selected');
316 $(this).dialog('close');
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);
324 PMA_ajaxRemoveMessage($msgbox);
325 // Show dialog if the request was successful
328 .append(data.message)
330 title: PMA_messages.strAddIndex,
334 checkIndexName("index_frm");
336 $('#index_columns td').each(function () {
337 $(this).css("width", $(this).width() + 'px');
339 $('#index_columns tbody').sortable();
340 // We dont need the slider at this moment.
341 $(this).find('fieldset.tblFooters').remove();
344 buttons: button_options,
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
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 = {};
380 button_options[PMA_messages.strGo] = function () {
381 if ($('#single_column').is(':checked')) {
383 'Key_name': (index_type == 'primary' ? 'PRIMARY' : ''),
384 'Index_type': index_type.toUpperCase()
386 PMA_showAddIndexDialog(source_array, (source_array.length), [col_index], col_index, index);
389 if ($('#composite_index').is(':checked')) {
390 if ($('input[name="composite_with"]').length !== 0 && $('input[name="composite_with"]:checked').length === 0
393 '<div class="error"><img src="themes/dot.gif" title=""' +
394 ' alt="" class="icon ic_s_error" /> ' +
395 PMA_messages.strFormEmpty +
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);
408 target_columns.push(col_index);
410 PMA_showAddIndexDialog(source_array, array_index, target_columns, col_index,
411 source_array[array_index]);
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');
422 var previous_index = $select_list.attr('data-index').split(',');
423 $select_list.find('option[value*="' + previous_index[0].toLowerCase() + '"]')
424 .attr('selected', 'selected');
428 var $dialog = $('<div/>').append($dialog_content).dialog({
432 title: PMA_messages.strAddIndex,
434 buttons: button_options,
436 $('#composite_index').on('change', function () {
437 if ($(this).is(':checked')) {
438 $dialog_content.append(PMA_getCompositeIndexList(source_array, col_index));
441 $('#single_column').on('change', function () {
442 if ($(this).is(':checked')) {
443 if ($('#composite_index_list').length) {
444 $('#composite_index_list').remove();
450 $('#composite_index').off('change');
451 $('#single_column').off('change');
458 * Unbind all event handlers before tearing down a page
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:
473 * <li>Showing/hiding inputs depending on the index type chosen</li>
474 * <li>create/edit/drop indexes</li>
477 AJAX.registerOnload('indexes.js', function () {
478 // Re-initialize variables.
479 primary_indexes = [];
482 fulltext_indexes = [];
485 checkIndexName("index_frm");
486 $('#select_index_type').live('change', function (event) {
487 event.preventDefault();
489 checkIndexName("index_frm");
493 * Ajax Event handler for 'Drop Index'
495 $('a.drop_primary_key_index_anchor.ajax').live('click', function (event) {
496 event.preventDefault();
497 var $anchor = $(this);
499 * @var $curr_row Object containing reference to the current field's row
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);
510 var question = escapeHtml(
511 $curr_row.children('td')
512 .children('.drop_primary_key_index_msg')
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();
528 $table_ref.siblings('div.notice').hide('medium');
530 // We are removing some of the rows only
531 toggleRowColors($rows_to_hide.last().next());
532 $rows_to_hide.hide("medium", function () {
536 if ($('#result_query').length) {
537 $('#result_query').remove();
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'));
545 PMA_commonActions.refreshMain(false, function () {
546 $("a.ajax[href^=#indexes]").click();
548 PMA_reloadNavigation();
550 PMA_ajaxShowMessage(PMA_messages.strErrorProcessingRequest + " : " + data.error, false);
553 }); // end $.PMA_confirm()
554 }); //end Drop Primary Key/Index
557 *Ajax event handler for index edit
559 $("#table_index tbody tr td.edit_index.ajax, #indexes .add_index.ajax").live('click', function (event) {
560 event.preventDefault();
562 if ($(this).find("a").length === 0) {
564 var valid = checkFormElementInRange(
565 $(this).closest('form')[0],
567 'Column count has to be larger than zero.'
572 url = $(this).closest('form').serialize();
573 title = PMA_messages.strAddIndex;
576 url = $(this).find("a").attr("href");
577 if (url.substring(0, 16) == "tbl_indexes.php?") {
578 url = url.substring(16, url.length);
580 title = PMA_messages.strEditIndex;
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();
592 * Ajax event handler for advanced index creation during table creation
593 * and column addition.
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);
610 // Select a source array.
611 switch (index_type) {
613 source_array = primary_indexes;
616 source_array = unique_indexes;
619 source_array = indexes;
622 source_array = fulltext_indexes;
626 if (source_array.length === 0) {
628 'Key_name': (index_type == 'primary' ? 'PRIMARY' : ''),
629 'Index_type': index_type.toUpperCase()
631 PMA_showAddIndexDialog(source_array, 0, [col_index], col_index, index);
633 if (index_type == 'primary') {
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);
640 target_columns.push(col_index);
642 PMA_showAddIndexDialog(source_array, array_index, target_columns, col_index,
643 source_array[array_index]);
645 // If there are multiple columns selected for an index, show advanced dialog.
646 PMA_indexTypeSelectionDialog(source_array, index_type, col_index);