').parent().html(); var tools = $result_query.find('.tools').wrap('
').parent().html(); // sqlOuter and tools will not be present if 'Show SQL queries' configuration is off if (typeof sqlOuter !== 'undefined' && typeof tools !== 'undefined') { $(g.o).find('.result_query:not(:last)').remove(); var $existing_query = $(g.o).find('.result_query'); // If two query box exists update query in second else add a second box if ($existing_query.find('div.sqlOuter').length > 1) { $existing_query.children(':nth-child(4)').remove(); $existing_query.children(':nth-child(4)').remove(); $existing_query.append(sqlOuter + tools); } else { $existing_query.append(sqlOuter + tools); } PMA_highlightSQL($existing_query); } } // hide and/or update the successfully saved cells g.hideEditCell(true, data); // remove the "Save edited cells" button $(g.o).find('div.save_edited').hide(); // update saved fields $(g.t).find('.to_be_saved') .removeClass('to_be_saved') .data('value', null) .data('original_data', null); g.isCellEdited = false; } else { PMA_ajaxShowMessage(data.error, false); if (!g.saveCellsAtOnce) { $(g.t).find('.to_be_saved') .removeClass('to_be_saved'); } } } }).done(function () { if (options !== undefined && options.move) { g.showEditCell(options.cell); } }); // end $.ajax() }, /** * Save edited cell, so it can be posted later. */ saveEditedCell: function () { /** * @var $this_field Object referring to the td that is being edited */ var $this_field = $(g.currentEditCell); var $test_element = ''; // to test the presence of a element var need_to_post = false; /** * @var field_name String containing the name of this field. * @see getFieldName() */ var field_name = getFieldName($(g.t), $this_field); /** * @var this_field_params Array temporary storage for the name/value of current field */ var this_field_params = {}; /** * @var is_null String capturing whether 'checkbox_null__' is checked. */ var is_null = $(g.cEdit).find('input:checkbox').is(':checked'); if ($(g.cEdit).find('.edit_area').is('.edit_area_loading')) { // the edit area is still loading (retrieving cell data), no need to post need_to_post = false; } else if (is_null) { if (!g.wasEditedCellNull) { this_field_params[field_name] = null; need_to_post = true; } } else { if ($this_field.is('.bit')) { this_field_params[field_name] = $(g.cEdit).find('.edit_box').val(); } else if ($this_field.is('.set')) { $test_element = $(g.cEdit).find('select'); this_field_params[field_name] = $test_element.map(function () { return $(this).val(); }).get().join(','); } else if ($this_field.is('.relation, .enum')) { // for relation and enumeration, take the results from edit box value, // because selected value from drop-down, new window or multiple // selection list will always be updated to the edit box this_field_params[field_name] = $(g.cEdit).find('.edit_box').val(); } else if ($this_field.hasClass('hex')) { if ($(g.cEdit).find('.edit_box').val().match(/^(0x)?[a-f0-9]*$/i) !== null) { this_field_params[field_name] = $(g.cEdit).find('.edit_box').val(); } else { var hexError = '' + PMA_messages.strEnterValidHex + ''; PMA_ajaxShowMessage(hexError, false); this_field_params[field_name] = PMA_getCellValue(g.currentEditCell); } } else { this_field_params[field_name] = $(g.cEdit).find('.edit_box').val(); } if (g.wasEditedCellNull || this_field_params[field_name] !== PMA_getCellValue(g.currentEditCell)) { need_to_post = true; } } if (need_to_post) { $(g.currentEditCell).addClass('to_be_saved') .data('value', this_field_params[field_name]); if (g.saveCellsAtOnce) { $(g.o).find('div.save_edited').show(); } g.isCellEdited = true; } return need_to_post; }, /** * Save or post currently edited cell, depending on the "saveCellsAtOnce" configuration. * * @param field Optional, this object contains a boolean named move (true, if called from move* functions) * and a to which the grid_edit should move */ saveOrPostEditedCell: function (options) { var saved = g.saveEditedCell(); // Check if $cfg['SaveCellsAtOnce'] is false if (!g.saveCellsAtOnce) { // Check if need_to_post is true if (saved) { // Check if this function called from 'move' functions if (options !== undefined && options.move) { g.postEditedCell(options); } else { g.postEditedCell(); } // need_to_post is false } else { // Check if this function called from 'move' functions if (options !== undefined && options.move) { g.hideEditCell(true); g.showEditCell(options.cell); // NOT called from 'move' functions } else { g.hideEditCell(true); } } // $cfg['SaveCellsAtOnce'] is true } else { // If need_to_post if (saved) { // If this function called from 'move' functions if (options !== undefined && options.move) { g.hideEditCell(true, true, false, options); g.showEditCell(options.cell); // NOT called from 'move' functions } else { g.hideEditCell(true, true); } } else { // If this function called from 'move' functions if (options !== undefined && options.move) { g.hideEditCell(true, false, false, options); g.showEditCell(options.cell); // NOT called from 'move' functions } else { g.hideEditCell(true); } } } }, /** * Initialize column resize feature. */ initColResize: function () { // create column resizer div g.cRsz = document.createElement('div'); g.cRsz.className = 'cRsz'; // get data columns in the first row of the table var $firstRowCols = $(g.t).find('tr:first th.draggable'); // create column borders $firstRowCols.each(function () { var cb = document.createElement('div'); // column border $(cb).addClass('colborder') .mousedown(function (e) { g.dragStartRsz(e, this); }); $(g.cRsz).append(cb); }); g.reposRsz(); // attach to global div $(g.gDiv).prepend(g.cRsz); }, /** * Initialize column reordering feature. */ initColReorder: function () { g.cCpy = document.createElement('div'); // column copy, to store copy of dragged column header g.cPointer = document.createElement('div'); // column pointer, used when reordering column // adjust g.cCpy g.cCpy.className = 'cCpy'; $(g.cCpy).hide(); // adjust g.cPointer g.cPointer.className = 'cPointer'; $(g.cPointer).css('visibility', 'hidden'); // set visibility to hidden instead of calling hide() to force browsers to cache the image in cPointer class // assign column reordering hint g.reorderHint = PMA_messages.strColOrderHint; // get data columns in the first row of the table var $firstRowCols = $(g.t).find('tr:first th.draggable'); // initialize column order $col_order = $(g.o).find('.col_order'); // check if column order is passed from PHP if ($col_order.length > 0) { g.colOrder = $col_order.val().split(','); for (var i = 0; i < g.colOrder.length; i++) { g.colOrder[i] = parseInt(g.colOrder[i], 10); } } else { g.colOrder = []; for (var i = 0; i < $firstRowCols.length; i++) { g.colOrder.push(i); } } // register events $(g.t).find('th.draggable') .mousedown(function (e) { $(g.o).addClass('turnOffSelect'); if (g.visibleHeadersCount > 1) { g.dragStartReorder(e, this); } }) .mouseenter(function () { if (g.visibleHeadersCount > 1) { $(this).css('cursor', 'move'); } else { $(this).css('cursor', 'inherit'); } }) .mouseleave(function () { g.showReorderHint = false; $(this).tooltip('option', { content: g.updateHint() }); }) .dblclick(function (e) { e.preventDefault(); $('') .prop('title', PMA_messages.strColNameCopyTitle) .addClass('modal-copy') .text(PMA_messages.strColNameCopyText) .append( $('') .prop('readonly', true) .val($(this).data('column')) ) .dialog({ resizable: false, modal: true }) .find('input').focus().select(); }); $(g.t).find('th.draggable a') .dblclick(function (e) { e.stopPropagation(); }); // restore column order when the restore button is clicked $(g.o).find('div.restore_column').click(function () { g.restoreColOrder(); }); // attach to global div $(g.gDiv).append(g.cPointer); $(g.gDiv).append(g.cCpy); // prevent default "dragstart" event when dragging a link $(g.t).find('th a').on('dragstart', function () { return false; }); // refresh the restore column button state g.refreshRestoreButton(); }, /** * Initialize column visibility feature. */ initColVisib: function () { g.cDrop = document.createElement('div'); // column drop-down arrows g.cList = document.createElement('div'); // column visibility list // adjust g.cDrop g.cDrop.className = 'cDrop'; // adjust g.cList g.cList.className = 'cList'; $(g.cList).hide(); // assign column visibility related hints g.showAllColText = PMA_messages.strShowAllCol; // get data columns in the first row of the table var $firstRowCols = $(g.t).find('tr:first th.draggable'); var i; // initialize column visibility var $col_visib = $(g.o).find('.col_visib'); // check if column visibility is passed from PHP if ($col_visib.length > 0) { g.colVisib = $col_visib.val().split(','); for (i = 0; i < g.colVisib.length; i++) { g.colVisib[i] = parseInt(g.colVisib[i], 10); } } else { g.colVisib = []; for (i = 0; i < $firstRowCols.length; i++) { g.colVisib.push(1); } } // make sure we have more than one column if ($firstRowCols.length > 1) { var $colVisibTh = $(g.t).find('th:not(.draggable)'); PMA_tooltip( $colVisibTh, 'th', PMA_messages.strColVisibHint ); // create column visibility drop-down arrow(s) $colVisibTh.each(function () { var $th = $(this); var cd = document.createElement('div'); // column drop-down arrow var pos = $th.position(); $(cd).addClass('coldrop') .click(function () { if (g.cList.style.display === 'none') { g.showColList(this); } else { g.hideColList(); } }); $(g.cDrop).append(cd); }); // add column visibility control g.cList.innerHTML = ''; var $listDiv = $(g.cList).find('div'); var tempClick = function () { if (g.toggleCol($(this).index())) { g.afterToggleCol(); } }; for (i = 0; i < $firstRowCols.length; i++) { var currHeader = $firstRowCols[i]; var listElmt = document.createElement('div'); $(listElmt).text($(currHeader).text()) .prepend(''); $listDiv.append(listElmt); // add event on click $(listElmt).click(tempClick); } // add "show all column" button var showAll = document.createElement('div'); $(showAll).addClass('showAllColBtn') .text(g.showAllColText); $(g.cList).append(showAll); $(showAll).click(function () { g.showAllColumns(); }); // prepend "show all column" button at top if the list is too long if ($firstRowCols.length > 10) { var clone = showAll.cloneNode(true); $(g.cList).prepend(clone); $(clone).click(function () { g.showAllColumns(); }); } } // hide column visibility list if we move outside the list $(g.t).find('td, th.draggable').mouseenter(function () { g.hideColList(); }); // attach to global div $(g.gDiv).append(g.cDrop); $(g.gDiv).append(g.cList); // some adjustment g.reposDrop(); }, /** * Move currently Editing Cell to Up */ moveUp: function (e) { e.preventDefault(); var $this_field = $(g.currentEditCell); var field_name = getFieldName($(g.t), $this_field); var where_clause = $this_field.parents('tr').first().find('.where_clause').val(); if (typeof where_clause === 'undefined') { where_clause = ''; } var found = false; var $found_row; var $prev_row; var j = 0; $this_field.parents('tr').first().parents('tbody').children().each(function () { if ($(this).find('.where_clause').val() === where_clause) { found = true; $found_row = $(this); } if (!found) { $prev_row = $(this); } }); var new_cell; if (found && $prev_row) { $prev_row.children('td').each(function () { if (getFieldName($(g.t), $(this)) === field_name) { new_cell = this; } }); } if (new_cell) { g.hideEditCell(false, false, false, { move : true, cell : new_cell }); } }, /** * Move currently Editing Cell to Down */ moveDown: function (e) { e.preventDefault(); var $this_field = $(g.currentEditCell); var field_name = getFieldName($(g.t), $this_field); var where_clause = $this_field.parents('tr').first().find('.where_clause').val(); if (typeof where_clause === 'undefined') { where_clause = ''; } var found = false; var $found_row; var $next_row; var j = 0; var next_row_found = false; $this_field.parents('tr').first().parents('tbody').children().each(function () { if ($(this).find('.where_clause').val() === where_clause) { found = true; $found_row = $(this); } if (found) { if (j >= 1 && ! next_row_found) { $next_row = $(this); next_row_found = true; } else { j++; } } }); var new_cell; if (found && $next_row) { $next_row.children('td').each(function () { if (getFieldName($(g.t), $(this)) === field_name) { new_cell = this; } }); } if (new_cell) { g.hideEditCell(false, false, false, { move : true, cell : new_cell }); } }, /** * Move currently Editing Cell to Left */ moveLeft: function (e) { e.preventDefault(); var $this_field = $(g.currentEditCell); var field_name = getFieldName($(g.t), $this_field); var where_clause = $this_field.parents('tr').first().find('.where_clause').val(); if (typeof where_clause === 'undefined') { where_clause = ''; } var found = false; var $found_row; var j = 0; $this_field.parents('tr').first().parents('tbody').children().each(function () { if ($(this).find('.where_clause').val() === where_clause) { found = true; $found_row = $(this); } }); var left_cell; var cell_found = false; if (found) { $found_row.children('td.grid_edit').each(function () { if (getFieldName($(g.t), $(this)) === field_name) { cell_found = true; } if (!cell_found) { left_cell = this; } }); } if (left_cell) { g.hideEditCell(false, false, false, { move : true, cell : left_cell }); } }, /** * Move currently Editing Cell to Right */ moveRight: function (e) { e.preventDefault(); var $this_field = $(g.currentEditCell); var field_name = getFieldName($(g.t), $this_field); var where_clause = $this_field.parents('tr').first().find('.where_clause').val(); if (typeof where_clause === 'undefined') { where_clause = ''; } var found = false; var $found_row; var j = 0; $this_field.parents('tr').first().parents('tbody').children().each(function () { if ($(this).find('.where_clause').val() === where_clause) { found = true; $found_row = $(this); } }); var right_cell; var cell_found = false; var next_cell_found = false; if (found) { $found_row.children('td.grid_edit').each(function () { if (getFieldName($(g.t), $(this)) === field_name) { cell_found = true; } if (cell_found) { if (j >= 1 && ! next_cell_found) { right_cell = this; next_cell_found = true; } else { j++; } } }); } if (right_cell) { g.hideEditCell(false, false, false, { move : true, cell : right_cell }); } }, /** * Initialize grid editing feature. */ initGridEdit: function () { function startGridEditing (e, cell) { if (g.isCellEditActive) { g.saveOrPostEditedCell(); } else { g.showEditCell(cell); } e.stopPropagation(); } function handleCtrlNavigation (e) { if ((e.ctrlKey && e.which === 38) || (e.altKey && e.which === 38)) { g.moveUp(e); } else if ((e.ctrlKey && e.which === 40) || (e.altKey && e.which === 40)) { g.moveDown(e); } else if ((e.ctrlKey && e.which === 37) || (e.altKey && e.which === 37)) { g.moveLeft(e); } else if ((e.ctrlKey && e.which === 39) || (e.altKey && e.which === 39)) { g.moveRight(e); } } // create cell edit wrapper element g.cEditStd = document.createElement('div'); g.cEdit = g.cEditStd; g.cEditTextarea = document.createElement('div'); // adjust g.cEditStd g.cEditStd.className = 'cEdit'; $(g.cEditStd).html(''); $(g.cEditStd).hide(); // adjust g.cEdit g.cEditTextarea.className = 'cEdit'; $(g.cEditTextarea).html(''); $(g.cEditTextarea).hide(); // assign cell editing hint g.cellEditHint = PMA_messages.strCellEditHint; g.saveCellWarning = PMA_messages.strSaveCellWarning; g.alertNonUnique = PMA_messages.strAlertNonUnique; g.gotoLinkText = PMA_messages.strGoToLink; // initialize cell editing configuration g.saveCellsAtOnce = $(g.o).find('.save_cells_at_once').val(); g.maxTruncatedLen = PMA_commonParams.get('LimitChars'); // register events $(g.t).find('td.data.click1') .click(function (e) { startGridEditing(e, this); // prevent default action when clicking on "link" in a table if ($(e.target).is('.grid_edit a')) { e.preventDefault(); } }); $(g.t).find('td.data.click2') .click(function (e) { var $cell = $(this); // In the case of relational link, We want single click on the link // to goto the link and double click to start grid-editing. var $link = $(e.target); if ($link.is('.grid_edit.relation a')) { e.preventDefault(); // get the click count and increase var clicks = $cell.data('clicks'); clicks = (typeof clicks === 'undefined') ? 1 : clicks + 1; if (clicks === 1) { // if there are no previous clicks, // start the single click timer var timer = setTimeout(function () { // temporarily remove ajax class so the page loader will not handle it, // submit and then add it back $link.removeClass('ajax'); AJAX.requestHandler.call($link[0]); $link.addClass('ajax'); $cell.data('clicks', 0); }, 700); $cell.data('clicks', clicks); $cell.data('timer', timer); } else { // this is a double click, cancel the single click timer // and make the click count 0 clearTimeout($cell.data('timer')); $cell.data('clicks', 0); // start grid-editing startGridEditing(e, this); } } }) .dblclick(function (e) { if ($(e.target).is('.grid_edit a')) { e.preventDefault(); } else { startGridEditing(e, this); } }); $(g.cEditStd).on('keydown', 'input.edit_box, select', handleCtrlNavigation); $(g.cEditStd).find('.edit_box').focus(function () { g.showEditArea(); }); $(g.cEditStd).on('keydown', '.edit_box, select', function (e) { if (e.which === 13) { // post on pressing "Enter" e.preventDefault(); g.saveOrPostEditedCell(); } }); $(g.cEditStd).keydown(function (e) { if (!g.isEditCellTextEditable) { // prevent text editing e.preventDefault(); } }); $(g.cEditTextarea).on('keydown', 'textarea.edit_box, select', handleCtrlNavigation); $(g.cEditTextarea).find('.edit_box').focus(function () { g.showEditArea(); }); $(g.cEditTextarea).on('keydown', '.edit_box, select', function (e) { if (e.which === 13 && !e.shiftKey) { // post on pressing "Enter" e.preventDefault(); g.saveOrPostEditedCell(); } }); $(g.cEditTextarea).keydown(function (e) { if (!g.isEditCellTextEditable) { // prevent text editing e.preventDefault(); } }); $('html').click(function (e) { // hide edit cell if the click is not fromDat edit area if ($(e.target).parents().index($(g.cEdit)) === -1 && !$(e.target).parents('.ui-datepicker-header').length && !$('.browse_foreign_modal.ui-dialog:visible').length && !$(e.target).closest('.dismissable').length ) { g.hideEditCell(); } }).keydown(function (e) { if (e.which === 27 && g.isCellEditActive) { // cancel on pressing "Esc" g.hideEditCell(true); } }); $(g.o).find('div.save_edited').click(function () { g.hideEditCell(); g.postEditedCell(); }); $(window).on('beforeunload', function () { if (g.isCellEdited) { return g.saveCellWarning; } }); // attach to global div $(g.gDiv).append(g.cEditStd); $(g.gDiv).append(g.cEditTextarea); // add hint for grid editing feature when hovering "Edit" link in each table row if (PMA_messages.strGridEditFeatureHint !== undefined) { PMA_tooltip( $(g.t).find('.edit_row_anchor a'), 'a', PMA_messages.strGridEditFeatureHint ); } } }; /** **************** * Initialize grid ******************/ // wrap all truncated data cells with span indicating the original length // todo update the original length after a grid edit $(t).find('td.data.truncated:not(:has(span))') .wrapInner(function () { return ''; }); // wrap remaining cells, except actions cell, with span $(t).find('th, td:not(:has(span))') .wrapInner(''); // create grid elements g.gDiv = document.createElement('div'); // create global div // initialize the table variable g.t = t; // enclosing .sqlqueryresults div g.o = $(t).parents('.sqlqueryresults'); // get data columns in the first row of the table var $firstRowCols = $(t).find('tr:first th.draggable'); // initialize visible headers count g.visibleHeadersCount = $firstRowCols.filter(':visible').length; // assign first column (actions) span if (! $(t).find('tr:first th:first').hasClass('draggable')) { // action header exist g.actionSpan = $(t).find('tr:first th:first').prop('colspan'); } else { g.actionSpan = 0; } // assign table create time // table_create_time will only available if we are in "Browse" tab g.tableCreateTime = $(g.o).find('.table_create_time').val(); // assign the hints g.sortHint = PMA_messages.strSortHint; g.strMultiSortHint = PMA_messages.strMultiSortHint; g.markHint = PMA_messages.strColMarkHint; g.copyHint = PMA_messages.strColNameCopyHint; // assign common hidden inputs var $common_hidden_inputs = $(g.o).find('div.common_hidden_inputs'); g.server = $common_hidden_inputs.find('input[name=server]').val(); g.db = $common_hidden_inputs.find('input[name=db]').val(); g.table = $common_hidden_inputs.find('input[name=table]').val(); // add table class $(t).addClass('pma_table'); // add relative position to global div so that resize handlers are correctly positioned $(g.gDiv).css('position', 'relative'); // link the global div $(t).before(g.gDiv); $(g.gDiv).append(t); // FEATURES enableResize = enableResize === undefined ? true : enableResize; enableReorder = enableReorder === undefined ? true : enableReorder; enableVisib = enableVisib === undefined ? true : enableVisib; enableGridEdit = enableGridEdit === undefined ? true : enableGridEdit; if (enableResize) { g.initColResize(); } // disable reordering for result from EXPLAIN or SHOW syntax, which do not have a table navigation panel if (enableReorder && $(g.o).find('table.navigation').length > 0) { g.initColReorder(); } if (enableVisib) { g.initColVisib(); } // make sure we have the ajax class if (enableGridEdit && $(t).is('.ajax')) { g.initGridEdit(); } // create tooltip for each with draggable class PMA_tooltip( $(t).find('th.draggable'), 'th', g.updateHint() ); // register events for hint tooltip (anchors inside draggable th) $(t).find('th.draggable a') .mouseenter(function () { g.showSortHint = true; g.showMultiSortHint = true; $(t).find('th.draggable').tooltip('option', { content: g.updateHint() }); }) .mouseleave(function () { g.showSortHint = false; g.showMultiSortHint = false; $(t).find('th.draggable').tooltip('option', { content: g.updateHint() }); }); // register events for dragging-related feature if (enableResize || enableReorder) { $(document).mousemove(function (e) { g.dragMove(e); }); $(document).mouseup(function (e) { $(g.o).removeClass('turnOffSelect'); g.dragEnd(e); }); } // some adjustment $(t).removeClass('data'); $(g.gDiv).addClass('data'); } /** * jQuery plugin to cancel selection in HTML code. */ (function ($) { $.fn.noSelect = function (p) { // no select plugin by Paulo P.Marinas var prevent = (p === null) ? true : p; var is_msie = navigator.userAgent.indexOf('MSIE') > -1 || !!window.navigator.userAgent.match(/Trident.*rv\:11\./); var is_firefox = navigator.userAgent.indexOf('Firefox') > -1; var is_safari = navigator.userAgent.indexOf('Safari') > -1; var is_opera = navigator.userAgent.indexOf('Presto') > -1; if (prevent) { return this.each(function () { if (is_msie || is_safari) { $(this).on('selectstart', false); } else if (is_firefox) { $(this).css('MozUserSelect', 'none'); $('body').trigger('focus'); } else if (is_opera) { $(this).on('mousedown', false); } else { $(this).attr('unselectable', 'on'); } }); } else { return this.each(function () { if (is_msie || is_safari) { $(this).off('selectstart'); } else if (is_firefox) { $(this).css('MozUserSelect', 'inherit'); } else if (is_opera) { $(this).off('mousedown'); } else { $(this).removeAttr('unselectable'); } }); } }; // end noSelect }(jQuery)); Simpan