indexes.js 27 KB

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