1/** 2 * @fileoverview function used for index manipulation pages 3 * @name Table Structure 4 * 5 * @requires jQuery 6 * @requires jQueryUI 7 * @required js/functions.js 8 */ 9 10/* global fulltextIndexes:writable, indexes:writable, primaryIndexes:writable, spatialIndexes:writable, uniqueIndexes:writable */ // js/functions.js 11 12var Indexes = {}; 13 14/** 15 * Returns the array of indexes based on the index choice 16 * 17 * @param {string} indexChoice index choice 18 * 19 * @return {null|object} 20 */ 21Indexes.getIndexArray = function (indexChoice) { 22 var sourceArray = null; 23 switch (indexChoice.toLowerCase()) { 24 case 'primary': 25 sourceArray = primaryIndexes; 26 break; 27 case 'unique': 28 sourceArray = uniqueIndexes; 29 break; 30 case 'index': 31 sourceArray = indexes; 32 break; 33 case 'fulltext': 34 sourceArray = fulltextIndexes; 35 break; 36 case 'spatial': 37 sourceArray = spatialIndexes; 38 break; 39 default: 40 return null; 41 } 42 return sourceArray; 43}; 44 45/** 46 * Hides/shows the inputs and submits appropriately depending 47 * on whether the index type chosen is 'SPATIAL' or not. 48 */ 49Indexes.checkIndexType = function () { 50 /** 51 * @var {JQuery<HTMLElement}, Dropdown to select the index choice. 52 */ 53 var $selectIndexChoice = $('#select_index_choice'); 54 /** 55 * @var {JQuery<HTMLElement}, Dropdown to select the index type. 56 */ 57 var $selectIndexType = $('#select_index_type'); 58 /** 59 * @var {JQuery<HTMLElement}, Table header for the size column. 60 */ 61 var $sizeHeader = $('#index_columns').find('thead tr').children('th').eq(1); 62 /** 63 * @var {JQuery<HTMLElement}, Inputs to specify the columns for the index. 64 */ 65 var $columnInputs = $('select[name="index[columns][names][]"]'); 66 /** 67 * @var {JQuery<HTMLElement}, Inputs to specify sizes for columns of the index. 68 */ 69 var $sizeInputs = $('input[name="index[columns][sub_parts][]"]'); 70 /** 71 * @var {JQuery<HTMLElement}, Footer containing the controllers to add more columns 72 */ 73 var $addMore = $('#index_frm').find('.add_more'); 74 if ($selectIndexChoice.val() === 'SPATIAL') { 75 // Disable and hide the size column 76 $sizeHeader.hide(); 77 $sizeInputs.each(function () { 78 $(this).prop('disabled', true).parent('td').hide(); 79 }); 80 81 // Disable and hide the columns of the index other than the first one 82 var initial = true; 83 $columnInputs.each(function () { 84 var $columnInput = $(this); 85 if (!initial) { 86 $columnInput.prop('disabled', true).parent('td').hide(); 87 } else { 88 initial = false; 89 } 90 }); 91 92 // Hide controllers to add more columns 93 $addMore.hide(); 94 } else { 95 // Enable and show the size column 96 $sizeHeader.show(); 97 $sizeInputs.each(function () { 98 $(this).prop('disabled', false).parent('td').show(); 99 }); 100 101 // Enable and show the columns of the index 102 $columnInputs.each(function () { 103 $(this).prop('disabled', false).parent('td').show(); 104 }); 105 106 // Show controllers to add more columns 107 $addMore.show(); 108 } 109 if ($selectIndexChoice.val() === 'SPATIAL' || $selectIndexChoice.val() === 'FULLTEXT') { 110 $selectIndexType.val('').prop('disabled', true); 111 } else { 112 $selectIndexType.prop('disabled', false); 113 } 114}; 115 116/** 117 * Sets current index information into form parameters. 118 * 119 * @param {any[]} sourceArray Array containing index columns 120 * @param {string} indexChoice Choice of index 121 * 122 * @return {void} 123 */ 124Indexes.setIndexFormParameters = function (sourceArray, indexChoice) { 125 if (indexChoice === 'index') { 126 $('input[name="indexes"]').val(JSON.stringify(sourceArray)); 127 } else { 128 $('input[name="' + indexChoice + '_indexes"]').val(JSON.stringify(sourceArray)); 129 } 130}; 131 132/** 133 * Removes a column from an Index. 134 * 135 * @param {string} colIndex Index of column in form 136 * 137 * @return {void} 138 */ 139Indexes.removeColumnFromIndex = function (colIndex) { 140 // Get previous index details. 141 var previousIndex = $('select[name="field_key[' + colIndex + ']"]').attr('data-index'); 142 if (previousIndex.length) { 143 previousIndex = previousIndex.split(','); 144 var sourceArray = Indexes.getIndexArray(previousIndex[0]); 145 if (sourceArray === null) { 146 return; 147 } 148
149 // Remove column from index array. 150 var sourceLength = sourceArray[previousIndex[1]].columns.length; 151 for (var i = 0; i < sourceLength; i++) { 152 if (sourceArray[previousIndex[1]].columns[i].col_index === colIndex) { 153 sourceArray[previousIndex[1]].columns.splice(i, 1); 154 } 155 } 156 157 // Remove index completely if no columns left. 158 if (sourceArray[previousIndex[1]].columns.length === 0) { 159 sourceArray.splice(previousIndex[1], 1); 160 } 161 162 // Update current index details. 163 $('select[name="field_key[' + colIndex + ']"]').attr('data-index', ''); 164 // Update form index parameters. 165 Indexes.setIndexFormParameters(sourceArray, previousIndex[0].toLowerCase()); 166 } 167}; 168 169/** 170 * Adds a column to an Index. 171 * 172 * @param {any[]} sourceArray Array holding corresponding indexes 173 * @param {string} arrayIndex Index of an INDEX in array 174 * @param {string} indexChoice Choice of Index 175 * @param {string} colIndex Index of column on form 176 * 177 * @return {void} 178 */ 179Indexes.addColumnToIndex = function (sourceArray, arrayIndex, indexChoice, colIndex) { 180 if (colIndex >= 0) { 181 // Remove column from other indexes (if any). 182 Indexes.removeColumnFromIndex(colIndex); 183 } 184 var indexName = $('input[name="index[Key_name]"]').val(); 185 var indexComment = $('input[name="index[Index_comment]"]').val(); 186 var keyBlockSize = $('input[name="index[Key_block_size]"]').val(); 187 var parser = $('input[name="index[Parser]"]').val(); 188 var indexType = $('select[name="index[Index_type]"]').val(); 189 var columns = []; 190 $('#index_columns').find('tbody').find('tr').each(function () { 191 // Get columns in particular order. 192 var colIndex = $(this).find('select[name="index[columns][names][]"]').val(); 193 var size = $(this).find('input[name="index[columns][sub_parts][]"]').val(); 194 columns.push({ 195 'col_index': colIndex, 196 'size': size 197 }); 198 }); 199 200 // Update or create an index. 201 sourceArray[arrayIndex] = { 202 'Key_name': indexName, 203 'Index_comment': indexComment, 204 'Index_choice': indexChoice.toUpperCase(), 205 'Key_block_size': keyBlockSize, 206 'Parser': parser, 207 'Index_type': indexType, 208 'columns': columns 209 }; 210 211 // Display index name (or column list) 212 var displayName = indexName; 213 if (displayName === '') { 214 var columnNames = []; 215 $.each(columns, function () { 216 columnNames.push($('input[name="field_name[' + this.col_index + ']"]').val()); 217 }); 218 displayName = '[' + columnNames.join(', ') + ']'; 219 } 220 $.each(columns, function () { 221 var id = 'index_name_' + this.col_index + '_8'; 222 var $name = $('#' + id); 223 if ($name.length === 0) { 224 $name = $('<a id="' + id + '" href="#" class="ajax show_index_dialog"></a>'); 225 $name.insertAfter($('select[name="field_key[' + this.col_index + ']"]')); 226 } 227 var $text = $('<small>').text(displayName); 228 $name.html($text); 229 }); 230 if (colIndex >= 0) { 231 // Update index details on form. 232 $('select[name="field_key[' + colIndex + ']"]').attr('data-index', indexChoice + ',' + arrayIndex); 233 } 234 Indexes.setIndexFormParameters(sourceArray, indexChoice.toLowerCase()); 235}; 236 237/** 238 * Get choices list for a column to create a composite index with. 239 * 240 * @param {any[]} sourceArray Array hodling columns for particular index 241 * @param {string} colIndex Choice of index 242 * 243 * @return {JQuery} jQuery Object 244 */ 245Indexes.getCompositeIndexList = function (sourceArray, colIndex) { 246 // Remove any previous list. 247 if ($('#composite_index_list').length) { 248 $('#composite_index_list').remove(); 249 } 250 251 // Html list. 252 var $compositeIndexList = $('<ul id="composite_index_list">' + '<div>' + Messages.strCompositeWith + '</div>' + '</ul>'); 253 254 // Add each column to list available for composite index. 255 var sourceLength = sourceArray.length; 256 var alreadyPresent = false; 257 for (var i = 0; i < sourceLength; i++) { 258 var subArrayLen = sourceArray[i].columns.length; 259 var columnNames = []; 260 for (var j = 0; j < subArrayLen; j++) { 261 columnNames.push($('input[name="field_name[' + sourceArray[i].columns[j].col_index + ']"]').val()); 262 if (colIndex === sourceArray[i].columns[j].col_index) { 263 alreadyPresent = true; 264 } 265 } 266 $compositeIndexList.append('<li>' + '<input type="radio" name="composite_with" ' + (alreadyPresent ? 'checked="checked"' : '') + ' id="composite_index_' + i + '" value="' + i + '">' + '<label for="composite_index_' + i + '">' + columnNames.join(', ') + '</label>' + '</li>'); 267 } 268 return $compositeIndexList; 269}; 270 271/** 272 * Shows 'Add Index' dialog. 273 * 274 * @param {any[]} sourceArray Array holding particular index 275 * @param {string} arrayIndex Index of an INDEX in array 276 * @param {any[]} targetColumns Columns for an INDEX 277 * @param {string} colIndex Index of column on form 278 * @param {object} index Index detail object 279 * @param {boolean} showDialog Whether to show index creation dialog or not 280 * 281 * @return {void} 282 */ 283Indexes.showAddIndexDialog = function (sourceArray, arrayIndex, targetColumns, colIndex, index, showDialog) { 284 var showDialogLocal = typeof showDialog !== 'undefined' ? showDialog : true; 285 // Prepare post-data. 286 var $table = $('input[name="table"]'); 287 var table = $table.length > 0 ? $table.val() : ''; 288 var postData = { 289 'server': CommonParams.get('server'), 290 'db': $('input[name="db"]').val(), 291 'table': table, 292 'ajax_request': 1, 293 'create_edit_table': 1, 294 'index': index 295 }; 296 var columns = {}; 297 for (var i = 0; i < targetColumns.length; i++) { 298 var columnName = $('input[name="field_name[' + targetColumns[i] + ']"]').val(); 299 var columnType = $('select[name="field_type[' + targetColumns[i] + ']"]').val().toLowerCase(); 300 columns[columnName] = [columnType, targetColumns[i]]; 301 } 302 postData.columns = JSON.stringify(columns); 303 var buttonOptions = { 304 [Messages.strGo]: { 305 text: Messages.strGo, 306 class: 'btn btn-primary' 307 }, 308 [Messages.strCancel]: { 309 text: Messages.strCancel, 310 class: 'btn btn-secondary' 311 } 312 }; 313 buttonOptions[Messages.strGo].click = function () { 314 var isMissingValue = false;
315 $('select[name="index[columns][names][]"]').each(function () { 316 if ($(this).val() === '') { 317 isMissingValue = true; 318 } 319 }); 320 if (!isMissingValue) { 321 Indexes.addColumnToIndex(sourceArray, arrayIndex, index.Index_choice, colIndex); 322 } else { 323 Functions.ajaxShowMessage('<div class="alert alert-danger" role="alert"><img src="themes/dot.gif" title="" alt=""' + ' class="icon ic_s_error"> ' + Messages.strMissingColumn + ' </div>', false); 324 return false; 325 } 326 $(this).remove(); 327 }; 328 buttonOptions[Messages.strCancel].click = function () { 329 if (colIndex >= 0) { 330 // Handle state on 'Cancel'. 331 var $selectList = $('select[name="field_key[' + colIndex + ']"]'); 332 if (!$selectList.attr('data-index').length) { 333 $selectList.find('option[value*="none"]').attr('selected', 'selected'); 334 } else { 335 var previousIndex = $selectList.attr('data-index').split(','); 336 $selectList.find('option[value*="' + previousIndex[0].toLowerCase() + '"]').attr('selected', 'selected'); 337 } 338 } 339 $(this).dialog('close'); 340 }; 341 var $msgbox = Functions.ajaxShowMessage(); 342 $.post('index.php?route=/table/indexes', postData, function (data) { 343 if (data.success === false) { 344 // in the case of an error, show the error message returned. 345 Functions.ajaxShowMessage(data.error, false); 346 } else { 347 Functions.ajaxRemoveMessage($msgbox); 348 var $div = $('<div></div>'); 349 if (showDialogLocal) { 350 // Show dialog if the request was successful 351 if ($('#addIndex').length > 0) { 352 $('#addIndex').remove(); 353 } 354 $div.append(data.message).dialog({ 355 classes: { 356 'ui-dialog-titlebar-close': 'btn-close' 357 }, 358 title: Messages.strAddIndex, 359 width: 450, 360 minHeight: 250, 361 create: function () { 362 $(this).on('keypress', function (e) { 363 if (e.which === 13 || e.keyCode === 13 || window.event.keyCode === 13) { 364 e.preventDefault(); 365 buttonOptions[Messages.strGo](); 366 $(this).remove(); 367 } 368 }); 369 }, 370 open: function () { 371 Functions.checkIndexName('index_frm'); 372 Functions.showHints($div); 373 $('#index_columns').find('td').each(function () { 374 $(this).css('width', $(this).width() + 'px'); 375 }); 376 $('#index_columns').find('tbody').sortable({ 377 axis: 'y', 378 containment: $('#index_columns').find('tbody'), 379 tolerance: 'pointer' 380 }); 381 }, 382 modal: true, 383 buttons: buttonOptions, 384 close: function () { 385 $(this).remove(); 386 } 387 }); 388 } else { 389 $div.append(data.message); 390 $div.css({ 391 'display': 'none' 392 }); 393 $div.appendTo($('body')); 394 $div.attr({ 395 'id': 'addIndex' 396 }); 397 var isMissingValue = false; 398 $('select[name="index[columns][names][]"]').each(function () { 399 if ($(this).val() === '') { 400 isMissingValue = true; 401 } 402 }); 403 if (!isMissingValue) { 404 Indexes.addColumnToIndex(sourceArray, arrayIndex, index.Index_choice, colIndex); 405 } else { 406 Functions.ajaxShowMessage('<div class="alert alert-danger" role="alert"><img src="themes/dot.gif" title="" alt=""' + ' class="icon ic_s_error"> ' + Messages.strMissingColumn + ' </div>', false); 407 return false; 408 } 409 } 410 } 411 }); 412}; 413 414/** 415 * Creates a advanced index type selection dialog. 416 * 417 * @param {any[]} sourceArray Array holding a particular type of indexes 418 * @param {string} indexChoice Choice of index 419 * @param {string} colIndex Index of new column on form 420 * 421 * @return {void} 422 */ 423Indexes.indexTypeSelectionDialog = function (sourceArray, indexChoice, colIndex) { 424 var $singleColumnRadio = $('<input type="radio" id="single_column" name="index_choice"' + ' checked="checked">' + '<label for="single_column">' + Messages.strCreateSingleColumnIndex + '</label>'); 425 var $compositeIndexRadio = $('<input type="radio" id="composite_index"' + ' name="index_choice">' + '<label for="composite_index">' + Messages.strCreateCompositeIndex + '</label>'); 426 var $dialogContent = $('<fieldset class="pma-fieldset" id="advance_index_creator"></fieldset>'); 427 $dialogContent.append('<legend>' + indexChoice.toUpperCase() + '</legend>'); 428
429 // For UNIQUE/INDEX type, show choice for single-column and composite index. 430 $dialogContent.append($singleColumnRadio); 431 $dialogContent.append($compositeIndexRadio); 432 var buttonOptions = { 433 [Messages.strGo]: { 434 text: Messages.strGo, 435 class: 'btn btn-primary' 436 }, 437 [Messages.strCancel]: { 438 text: Messages.strCancel, 439 class: 'btn btn-secondary' 440 } 441 }; 442 443 // 'OK' operation. 444 buttonOptions[Messages.strGo].click = function () { 445 if ($('#single_column').is(':checked')) { 446 var index = { 447 'Key_name': indexChoice === 'primary' ? 'PRIMARY' : '', 448 'Index_choice': indexChoice.toUpperCase() 449 }; 450 Indexes.showAddIndexDialog(sourceArray, sourceArray.length, [colIndex], colIndex, index); 451 } 452 if ($('#composite_index').is(':checked')) { 453 if ($('input[name="composite_with"]').length !== 0 && $('input[name="composite_with"]:checked').length === 0) { 454 Functions.ajaxShowMessage('<div class="alert alert-danger" role="alert"><img src="themes/dot.gif" title=""' + ' alt="" class="icon ic_s_error"> ' + Messages.strFormEmpty + ' </div>', false); 455 return false; 456 } 457 var arrayIndex = $('input[name="composite_with"]:checked').val(); 458 var sourceLength = sourceArray[arrayIndex].columns.length; 459 var targetColumns = []; 460 for (var i = 0; i < sourceLength; i++) { 461 targetColumns.push(sourceArray[arrayIndex].columns[i].col_index); 462 } 463 targetColumns.push(colIndex); 464 Indexes.showAddIndexDialog(sourceArray, arrayIndex, targetColumns, colIndex, sourceArray[arrayIndex]); 465 } 466 $(this).remove(); 467 }; 468 buttonOptions[Messages.strCancel].click = function () { 469 // Handle state on 'Cancel'. 470 var $selectList = $('select[name="field_key[' + colIndex + ']"]'); 471 if (!$selectList.attr('data-index').length) { 472 $selectList.find('option[value*="none"]').attr('selected', 'selected'); 473 } else { 474 var previousIndex = $selectList.attr('data-index').split(','); 475 $selectList.find('option[value*="' + previousIndex[0].toLowerCase() + '"]').attr('selected', 'selected'); 476 } 477 $(this).remove(); 478 }; 479 $('<div></div>').append($dialogContent).dialog({ 480 classes: { 481 'ui-dialog-titlebar-close': 'btn-close' 482 }, 483 minWidth: 525, 484 minHeight: 200, 485 modal: true, 486 title: Messages.strAddIndex, 487 resizable: false, 488 buttons: buttonOptions, 489 open: function () { 490 $('#composite_index').on('change', function () { 491 if ($(this).is(':checked')) { 492 $dialogContent.append(Indexes.getCompositeIndexList(sourceArray, colIndex)); 493 } 494 }); 495 $('#single_column').on('change', function () { 496 if ($(this).is(':checked')) { 497 if ($('#composite_index_list').length) { 498 $('#composite_index_list').remove(); 499 } 500 } 501 }); 502 }, 503 close: function () { 504 $('#composite_index').off('change'); 505 $('#single_column').off('change'); 506 $(this).remove(); 507 } 508 }); 509}; 510 511/** 512 * Unbind all event handlers before tearing down a page 513 */ 514AJAX.registerTeardown('indexes.js', function () { 515 $(document).off('click', '#save_index_frm'); 516 $(document).off('click', '#preview_index_frm'); 517 $(document).off('change', '#select_index_choice'); 518 $(document).off('click', 'a.drop_primary_key_index_anchor.ajax'); 519 $(document).off('click', '#table_index tbody tr td.edit_index.ajax, #index_div .add_index.ajax'); 520 $(document).off('click', '#table_index tbody tr td.rename_index.ajax'); 521 $(document).off('click', '#index_frm input[type=submit]'); 522 $('body').off('change', 'select[name*="field_key"]'); 523 $(document).off('click', '.show_index_dialog'); 524}); 525 526/** 527 * @description <p>Ajax scripts for table index page</p> 528 * 529 * Actions ajaxified here: 530 * <ul> 531 * <li>Showing/hiding inputs depending on the index type chosen</li> 532 * <li>create/edit/drop indexes</li> 533 * </ul> 534 */ 535AJAX.registerOnload('indexes.js', function () { 536 // Re-initialize variables. 537 primaryIndexes = []; 538 uniqueIndexes = []; 539 indexes = []; 540 fulltextIndexes = []; 541 spatialIndexes = []; 542 543 // for table creation form 544 var $engineSelector = $('.create_table_form select[name=tbl_storage_engine]'); 545 if ($engineSelector.length) { 546 Functions.hideShowConnection($engineSelector); 547 }
548 var $form = $('#index_frm'); 549 if ($form.length > 0) { 550 Functions.showIndexEditDialog($form); 551 } 552 $(document).on('click', '#save_index_frm', function (event) { 553 event.preventDefault(); 554 var $form = $('#index_frm'); 555 var argsep = CommonParams.get('arg_separator'); 556 var submitData = $form.serialize() + argsep + 'do_save_data=1' + argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true'; 557 Functions.ajaxShowMessage(Messages.strProcessingRequest); 558 AJAX.source = $form; 559 $.post($form.attr('action'), submitData, AJAX.responseHandler); 560 }); 561 $(document).on('click', '#preview_index_frm', function (event) { 562 event.preventDefault(); 563 Functions.previewSql($('#index_frm')); 564 }); 565 $(document).on('change', '#select_index_choice', function (event) { 566 event.preventDefault(); 567 Indexes.checkIndexType(); 568 Functions.checkIndexName('index_frm'); 569 }); 570 571 /** 572 * Ajax Event handler for 'Drop Index' 573 */ 574 $(document).on('click', 'a.drop_primary_key_index_anchor.ajax', function (event) { 575 event.preventDefault(); 576 var $anchor = $(this); 577 /** 578 * @var $currRow Object containing reference to the current field's row 579 */ 580 var $currRow = $anchor.parents('tr'); 581 /** @var {number} rows Number of columns in the key */ 582 var rows = $anchor.parents('td').attr('rowspan') || 1; 583 /** @var {number} $rowsToHide Rows that should be hidden */ 584 var $rowsToHide = $currRow; 585 for (var i = 1, $lastRow = $currRow.next(); i < rows; i++, $lastRow = $lastRow.next()) { 586 $rowsToHide = $rowsToHide.add($lastRow); 587 } 588 var question = $currRow.children('td').children('.drop_primary_key_index_msg').val(); 589 Functions.confirmPreviewSql(question, $anchor.attr('href'), function (url) { 590 var $msg = Functions.ajaxShowMessage(Messages.strDroppingPrimaryKeyIndex, false); 591 var params = Functions.getJsConfirmCommonParam(this, $anchor.getPostData()); 592 $.post(url, params, function (data) { 593 if (typeof data !== 'undefined' && data.success === true) { 594 Functions.ajaxRemoveMessage($msg); 595 var $tableRef = $rowsToHide.closest('table'); 596 if ($rowsToHide.length === $tableRef.find('tbody > tr').length) { 597 // We are about to remove all rows from the table 598 $tableRef.hide('medium', function () { 599 $('div.no_indexes_defined').show('medium'); 600 $rowsToHide.remove(); 601 }); 602 $tableRef.siblings('.alert-primary').hide('medium'); 603 } else { 604 // We are removing some of the rows only 605 $rowsToHide.hide('medium', function () { 606 $(this).remove(); 607 }); 608 } 609 if ($('.result_query').length) { 610 $('.result_query').remove(); 611 } 612 if (data.sql_query) { 613 $('<div class="result_query"></div>').html(data.sql_query).prependTo('#structure_content'); 614 Functions.highlightSql($('#page_content')); 615 } 616 Navigation.reload(); 617 CommonActions.refreshMain('index.php?route=/table/structure'); 618 } else { 619 Functions.ajaxShowMessage(Messages.strErrorProcessingRequest + ' : ' + data.error, false); 620 } 621 }); // end $.post() 622 }); 623 }); // end Drop Primary Key/Index 624 625 /** 626 * Ajax event handler for index edit 627 **/ 628 $(document).on('click', '#table_index tbody tr td.edit_index.ajax, #index_div .add_index.ajax', function (event) { 629 event.preventDefault(); 630 var url; 631 var title; 632 if ($(this).find('a').length === 0) { 633 // Add index 634 var valid = Functions.checkFormElementInRange($(this).closest('form')[0], 'added_fields', 'Column count has to be larger than zero.'); 635 if (!valid) { 636 return; 637 } 638 url = $(this).closest('form').serialize(); 639 title = Messages.strAddIndex; 640 } else { 641 // Edit index 642 url = $(this).find('a').getPostData(); 643 title = Messages.strEditIndex; 644 } 645 url += CommonParams.get('arg_separator') + 'ajax_request=true'; 646 Functions.indexEditorDialog(url, title, function (data) { 647 CommonParams.set('db', data.params.db); 648 CommonParams.set('table', data.params.table); 649 CommonActions.refreshMain('index.php?route=/table/structure'); 650 }); 651 }); 652 653 /** 654 * Ajax event handler for index rename 655 **/ 656 $(document).on('click', '#table_index tbody tr td.rename_index.ajax', function (event) { 657 event.preventDefault(); 658 var url = $(this).find('a').getPostData(); 659 var title = Messages.strRenameIndex; 660 url += CommonParams.get('arg_separator') + 'ajax_request=true'; 661 Functions.indexRenameDialog(url, title, function (data) { 662 CommonParams.set('db', data.params.db); 663 CommonParams.set('table', data.params.table); 664 CommonActions.refreshMain('index.php?route=/table/structure'); 665 }); 666 }); 667 668 /** 669 * Ajax event handler for advanced index creation during table creation 670 * and column addition. 671 */ 672 $('body').on('change', 'select[name*="field_key"]', function (e, showDialog) { 673 var showDialogLocal = typeof showDialog !== 'undefined' ? showDialog : true; 674 // Index of column on Table edit and create page. 675 var colIndex = /\d+/.exec($(this).attr('name')); 676 colIndex = colIndex[0]; 677 // Choice of selected index. 678 var indexChoice = /[a-z]+/.exec($(this).val()); 679 indexChoice = indexChoice[0]; 680 // Array containing corresponding indexes. 681 var sourceArray = null; 682 if (indexChoice === 'none') { 683 Indexes.removeColumnFromIndex(colIndex); 684 var id = 'index_name_' + '0' + '_8';
685 var $name = $('#' + id); 686 if ($name.length === 0) { 687 $name = $('<a id="' + id + '" href="#" class="ajax show_index_dialog"></a>'); 688 $name.insertAfter($('select[name="field_key[' + '0' + ']"]')); 689 } 690 $name.html(''); 691 return false; 692 } 693 694 // Select a source array. 695 sourceArray = Indexes.getIndexArray(indexChoice); 696 if (sourceArray === null) { 697 return; 698 } 699 if (sourceArray.length === 0) { 700 var index = { 701 'Key_name': indexChoice === 'primary' ? 'PRIMARY' : '', 702 'Index_choice': indexChoice.toUpperCase() 703 }; 704 Indexes.showAddIndexDialog(sourceArray, 0, [colIndex], colIndex, index, showDialogLocal); 705 } else { 706 if (indexChoice === 'primary') { 707 var arrayIndex = 0; 708 var sourceLength = sourceArray[arrayIndex].columns.length; 709 var targetColumns = []; 710 for (var i = 0; i < sourceLength; i++) { 711 targetColumns.push(sourceArray[arrayIndex].columns[i].col_index); 712 } 713 targetColumns.push(colIndex); 714 Indexes.showAddIndexDialog(sourceArray, arrayIndex, targetColumns, colIndex, sourceArray[arrayIndex], showDialogLocal); 715 } else { 716 // If there are multiple columns selected for an index, show advanced dialog. 717 Indexes.indexTypeSelectionDialog(sourceArray, indexChoice, colIndex); 718 } 719 } 720 }); 721 $(document).on('click', '.show_index_dialog', function (e) { 722 e.preventDefault(); 723 724 // Get index details. 725 var previousIndex = $(this).prev('select').attr('data-index').split(','); 726 var indexChoice = previousIndex[0]; 727 var arrayIndex = previousIndex[1]; 728 var sourceArray = Indexes.getIndexArray(indexChoice); 729 if (sourceArray !== null) { 730 var sourceLength = sourceArray[arrayIndex].columns.length; 731 var targetColumns = []; 732 for (var i = 0; i < sourceLength; i++) { 733 targetColumns.push(sourceArray[arrayIndex].columns[i].col_index); 734 } 735 Indexes.showAddIndexDialog(sourceArray, arrayIndex, targetColumns, -1, sourceArray[arrayIndex]); 736 } 737 }); 738 $('#index_frm').on('submit', function () { 739 if (typeof this.elements['index[Key_name]'].disabled !== 'undefined') { 740 this.elements['index[Key_name]'].disabled = false; 741 } 742 }); 743});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.