diff options
| author | Charles Cabergs <me@cacharle.xyz> | 2020-07-27 10:05:23 +0200 |
|---|---|---|
| committer | Charles Cabergs <me@cacharle.xyz> | 2020-07-27 10:05:23 +0200 |
| commit | 5bf66662a9bdd62c5bccab15e607cd95cfb8fcab (patch) | |
| tree | 39a1a4629749056191c05dfd899f931701b7acf3 /srcs/phpmyadmin/js/makegrid.js | |
| parent | 5afd237bbd22028b85532b8c0b3fcead49a00764 (diff) | |
| download | ft_server-5bf66662a9bdd62c5bccab15e607cd95cfb8fcab.tar.gz ft_server-5bf66662a9bdd62c5bccab15e607cd95cfb8fcab.tar.bz2 ft_server-5bf66662a9bdd62c5bccab15e607cd95cfb8fcab.zip | |
Removed wordpress and phpmyadmin, my server doesn't handle it well and it brings shame on my famillyHEADmaster
Diffstat (limited to 'srcs/phpmyadmin/js/makegrid.js')
| -rw-r--r-- | srcs/phpmyadmin/js/makegrid.js | 2295 |
1 files changed, 0 insertions, 2295 deletions
diff --git a/srcs/phpmyadmin/js/makegrid.js b/srcs/phpmyadmin/js/makegrid.js deleted file mode 100644 index 8780c95..0000000 --- a/srcs/phpmyadmin/js/makegrid.js +++ /dev/null @@ -1,2295 +0,0 @@ -/* vim: set expandtab sw=4 ts=4 sts=4: */ -/** - * Create advanced table (resize, reorder, and show/hide columns; and also grid editing). - * This function is designed mainly for table DOM generated from browsing a table in the database. - * For using this function in other table DOM, you may need to: - * - add "draggable" class in the table header <th>, in order to make it resizable, sortable or hidable - * - have at least one non-"draggable" header in the table DOM for placing column visibility drop-down arrow - * - pass the value "false" for the parameter "enableGridEdit" - * - adjust other parameter value, to select which features that will be enabled - * - * @param t the table DOM element - * @param enableResize Optional, if false, column resizing feature will be disabled - * @param enableReorder Optional, if false, column reordering feature will be disabled - * @param enableVisib Optional, if false, show/hide column feature will be disabled - * @param enableGridEdit Optional, if false, grid editing feature will be disabled - */ -// eslint-disable-next-line no-unused-vars -var makeGrid = function (t, enableResize, enableReorder, enableVisib, enableGridEdit) { - var isResizeEnabled = enableResize === undefined ? true : enableResize; - var isReorderEnabled = enableReorder === undefined ? true : enableReorder; - var isVisibEnabled = enableVisib === undefined ? true : enableVisib; - var isGridEditEnabled = enableGridEdit === undefined ? true : enableGridEdit; - - var g = { - /** ********* - * Constant - ***********/ - minColWidth: 15, - - - /** ********* - * Variables, assigned with default value, changed later - ***********/ - actionSpan: 5, // number of colspan in Actions header in a table - tableCreateTime: null, // table creation time, used for saving column order and visibility to server, only available in "Browse tab" - - // Column reordering variables - colOrder: [], // array of column order - - // Column visibility variables - colVisib: [], // array of column visibility - showAllColText: '', // string, text for "show all" button under column visibility list - visibleHeadersCount: 0, // number of visible data headers - - // Table hint variables - reorderHint: '', // string, hint for column reordering - sortHint: '', // string, hint for column sorting - markHint: '', // string, hint for column marking - copyHint: '', // string, hint for copy column name - showReorderHint: false, - showSortHint: false, - showMarkHint: false, - - // Grid editing - isCellEditActive: false, // true if current focus is in edit cell - isEditCellTextEditable: false, // true if current edit cell is editable in the text input box (not textarea) - currentEditCell: null, // reference to <td> that currently being edited - cellEditHint: '', // hint shown when doing grid edit - gotoLinkText: '', // "Go to link" text - wasEditedCellNull: false, // true if last value of the edited cell was NULL - maxTruncatedLen: 0, // number of characters that can be displayed in a cell - saveCellsAtOnce: false, // $cfg[saveCellsAtOnce] - isCellEdited: false, // true if at least one cell has been edited - saveCellWarning: '', // string, warning text when user want to leave a page with unsaved edited data - lastXHR : null, // last XHR object used in AJAX request - isSaving: false, // true when currently saving edited data, used to handle double posting caused by pressing ENTER in grid edit text box in Chrome browser - alertNonUnique: '', // string, alert shown when saving edited nonunique table - - // Common hidden inputs - token: null, - server: null, - db: null, - table: null, - - - /** ********** - * Functions - ************/ - - /** - * Start to resize column. Called when clicking on column separator. - * - * @param e event - * @param obj dragged div object - */ - dragStartRsz: function (e, obj) { - var n = $(g.cRsz).find('div').index(obj); // get the index of separator (i.e., column index) - $(obj).addClass('colborder_active'); - g.colRsz = { - x0: e.pageX, - n: n, - obj: obj, - objLeft: $(obj).position().left, - objWidth: $(g.t).find('th.draggable:visible:eq(' + n + ') span').outerWidth() - }; - $(document.body).css('cursor', 'col-resize').noSelect(); - if (g.isCellEditActive) { - g.hideEditCell(); - } - }, - - /** - * Start to reorder column. Called when clicking on table header. - * - * @param e event - * @param obj table header object - */ - dragStartReorder: function (e, obj) { - // prepare the cCpy (column copy) and cPointer (column pointer) from the dragged column - $(g.cCpy).text($(obj).text()); - var objPos = $(obj).position(); - $(g.cCpy).css({ - top: objPos.top + 20, - left: objPos.left, - height: $(obj).height(), - width: $(obj).width() - }); - $(g.cPointer).css({ - top: objPos.top - }); - - // get the column index, zero-based - var n = g.getHeaderIdx(obj); - - g.colReorder = { - x0: e.pageX, - y0: e.pageY, - n: n, - newn: n, - obj: obj, - objTop: objPos.top, - objLeft: objPos.left - }; - - $(document.body).css('cursor', 'move').noSelect(); - if (g.isCellEditActive) { - g.hideEditCell(); - } - }, - - /** - * Handle mousemove event when dragging. - * - * @param e event - */ - dragMove: function (e) { - var dx; - if (g.colRsz) { - dx = e.pageX - g.colRsz.x0; - if (g.colRsz.objWidth + dx > g.minColWidth) { - $(g.colRsz.obj).css('left', g.colRsz.objLeft + dx + 'px'); - } - } else if (g.colReorder) { - // dragged column animation - dx = e.pageX - g.colReorder.x0; - $(g.cCpy) - .css('left', g.colReorder.objLeft + dx) - .show(); - - // pointer animation - var hoveredCol = g.getHoveredCol(e); - if (hoveredCol) { - var newn = g.getHeaderIdx(hoveredCol); - g.colReorder.newn = newn; - if (newn !== g.colReorder.n) { - // show the column pointer in the right place - var colPos = $(hoveredCol).position(); - var newleft = newn < g.colReorder.n ? - colPos.left : - colPos.left + $(hoveredCol).outerWidth(); - $(g.cPointer) - .css({ - left: newleft, - visibility: 'visible' - }); - } else { - // no movement to other column, hide the column pointer - $(g.cPointer).css('visibility', 'hidden'); - } - } - } - }, - - /** - * Stop the dragging action. - * - * @param e event - */ - dragEnd: function (e) { - if (g.colRsz) { - var dx = e.pageX - g.colRsz.x0; - var nw = g.colRsz.objWidth + dx; - if (nw < g.minColWidth) { - nw = g.minColWidth; - } - var n = g.colRsz.n; - // do the resizing - g.resize(n, nw); - - g.reposRsz(); - g.reposDrop(); - g.colRsz = false; - $(g.cRsz).find('div').removeClass('colborder_active'); - Sql.rearrangeStickyColumns($(t).prev('.sticky_columns'), $(t)); - } else if (g.colReorder) { - // shift columns - if (g.colReorder.newn !== g.colReorder.n) { - g.shiftCol(g.colReorder.n, g.colReorder.newn); - // assign new position - var objPos = $(g.colReorder.obj).position(); - g.colReorder.objTop = objPos.top; - g.colReorder.objLeft = objPos.left; - g.colReorder.n = g.colReorder.newn; - // send request to server to remember the column order - if (g.tableCreateTime) { - g.sendColPrefs(); - } - g.refreshRestoreButton(); - } - - // animate new column position - $(g.cCpy).stop(true, true) - .animate({ - top: g.colReorder.objTop, - left: g.colReorder.objLeft - }, 'fast') - .fadeOut(); - $(g.cPointer).css('visibility', 'hidden'); - - g.colReorder = false; - Sql.rearrangeStickyColumns($(t).prev('.sticky_columns'), $(t)); - } - $(document.body).css('cursor', 'inherit').noSelect(false); - }, - - /** - * Resize column n to new width "nw" - * - * @param n zero-based column index - * @param nw new width of the column in pixel - */ - resize: function (n, nw) { - $(g.t).find('tr').each(function () { - $(this).find('th.draggable:visible:eq(' + n + ') span,' + - 'td:visible:eq(' + (g.actionSpan + n) + ') span') - .css('width', nw); - }); - }, - - /** - * Reposition column resize bars. - */ - reposRsz: function () { - $(g.cRsz).find('div').hide(); - var $firstRowCols = $(g.t).find('tr:first th.draggable:visible'); - var $resizeHandles = $(g.cRsz).find('div').removeClass('condition'); - $(g.t).find('table.pma_table').find('thead th:first').removeClass('before-condition'); - for (var n = 0, l = $firstRowCols.length; n < l; n++) { - var $col = $($firstRowCols[n]); - var colWidth; - if (navigator.userAgent.toLowerCase().indexOf('safari') !== -1) { - colWidth = $col.outerWidth(); - } else { - colWidth = $col.outerWidth(true); - } - $($resizeHandles[n]).css('left', $col.position().left + colWidth) - .show(); - if ($col.hasClass('condition')) { - $($resizeHandles[n]).addClass('condition'); - if (n > 0) { - $($resizeHandles[n - 1]).addClass('condition'); - } - } - } - if ($($resizeHandles[0]).hasClass('condition')) { - $(g.t).find('thead th:first').addClass('before-condition'); - } - $(g.cRsz).css('height', $(g.t).height()); - }, - - /** - * Shift column from index oldn to newn. - * - * @param oldn old zero-based column index - * @param newn new zero-based column index - */ - shiftCol: function (oldn, newn) { - $(g.t).find('tr').each(function () { - if (newn < oldn) { - $(this).find('th.draggable:eq(' + newn + '),' + - 'td:eq(' + (g.actionSpan + newn) + ')') - .before($(this).find('th.draggable:eq(' + oldn + '),' + - 'td:eq(' + (g.actionSpan + oldn) + ')')); - } else { - $(this).find('th.draggable:eq(' + newn + '),' + - 'td:eq(' + (g.actionSpan + newn) + ')') - .after($(this).find('th.draggable:eq(' + oldn + '),' + - 'td:eq(' + (g.actionSpan + oldn) + ')')); - } - }); - // reposition the column resize bars - g.reposRsz(); - - // adjust the column visibility list - if (newn < oldn) { - $(g.cList).find('.lDiv div:eq(' + newn + ')') - .before($(g.cList).find('.lDiv div:eq(' + oldn + ')')); - } else { - $(g.cList).find('.lDiv div:eq(' + newn + ')') - .after($(g.cList).find('.lDiv div:eq(' + oldn + ')')); - } - // adjust the colOrder - var tmp = g.colOrder[oldn]; - g.colOrder.splice(oldn, 1); - g.colOrder.splice(newn, 0, tmp); - // adjust the colVisib - if (g.colVisib.length > 0) { - tmp = g.colVisib[oldn]; - g.colVisib.splice(oldn, 1); - g.colVisib.splice(newn, 0, tmp); - } - }, - - /** - * Find currently hovered table column's header (excluding actions column). - * - * @param e event - * @return the hovered column's th object or undefined if no hovered column found. - */ - getHoveredCol: function (e) { - var hoveredCol; - var $headers = $(g.t).find('th.draggable:visible'); - $headers.each(function () { - var left = $(this).offset().left; - var right = left + $(this).outerWidth(); - if (left <= e.pageX && e.pageX <= right) { - hoveredCol = this; - } - }); - return hoveredCol; - }, - - /** - * Get a zero-based index from a <th class="draggable"> tag in a table. - * - * @param obj table header <th> object - * @return zero-based index of the specified table header in the set of table headers (visible or not) - */ - getHeaderIdx: function (obj) { - return $(obj).parents('tr').find('th.draggable').index(obj); - }, - - /** - * Reposition the columns back to normal order. - */ - restoreColOrder: function () { - // use insertion sort, since we already have shiftCol function - for (var i = 1; i < g.colOrder.length; i++) { - var x = g.colOrder[i]; - var j = i - 1; - while (j >= 0 && x < g.colOrder[j]) { - j--; - } - if (j !== i - 1) { - g.shiftCol(i, j + 1); - } - } - if (g.tableCreateTime) { - // send request to server to remember the column order - g.sendColPrefs(); - } - g.refreshRestoreButton(); - }, - - /** - * Send column preferences (column order and visibility) to the server. - */ - sendColPrefs: function () { - if ($(g.t).is('.ajax')) { // only send preferences if ajax class - var postParams = { - 'ajax_request': true, - 'db': g.db, - 'table': g.table, - 'token': g.token, - 'server': g.server, - 'set_col_prefs': true, - 'table_create_time': g.tableCreateTime - }; - if (g.colOrder.length > 0) { - $.extend(postParams, { 'col_order': g.colOrder.toString() }); - } - if (g.colVisib.length > 0) { - $.extend(postParams, { 'col_visib': g.colVisib.toString() }); - } - $.post('sql.php', postParams, function (data) { - if (data.success !== true) { - var $tempDiv = $(document.createElement('div')); - $tempDiv.html(data.error); - $tempDiv.addClass('error'); - Functions.ajaxShowMessage($tempDiv, false); - } - }); - } - }, - - /** - * Refresh restore button state. - * Make restore button disabled if the table is similar with initial state. - */ - refreshRestoreButton: function () { - // check if table state is as initial state - var isInitial = true; - for (var i = 0; i < g.colOrder.length; i++) { - if (g.colOrder[i] !== i) { - isInitial = false; - break; - } - } - // check if only one visible column left - var isOneColumn = g.visibleHeadersCount === 1; - // enable or disable restore button - if (isInitial || isOneColumn) { - $(g.o).find('div.restore_column').hide(); - } else { - $(g.o).find('div.restore_column').show(); - } - }, - - /** - * Update current hint using the boolean values (showReorderHint, showSortHint, etc.). - * - */ - updateHint: function () { - var text = ''; - if (!g.colRsz && !g.colReorder) { // if not resizing or dragging - if (g.visibleHeadersCount > 1) { - g.showReorderHint = true; - } - if ($(t).find('th.marker').length > 0) { - g.showMarkHint = true; - } - if (g.showSortHint && g.sortHint) { - text += text.length > 0 ? '<br>' : ''; - text += '- ' + g.sortHint; - } - if (g.showMultiSortHint && g.strMultiSortHint) { - text += text.length > 0 ? '<br>' : ''; - text += '- ' + g.strMultiSortHint; - } - if (g.showMarkHint && - g.markHint && - ! g.showSortHint && // we do not show mark hint, when sort hint is shown - g.showReorderHint && - g.reorderHint - ) { - text += text.length > 0 ? '<br>' : ''; - text += '- ' + g.reorderHint; - text += text.length > 0 ? '<br>' : ''; - text += '- ' + g.markHint; - text += text.length > 0 ? '<br>' : ''; - text += '- ' + g.copyHint; - } - } - return text; - }, - - /** - * Toggle column's visibility. - * After calling this function and it returns true, afterToggleCol() must be called. - * - * @return boolean True if the column is toggled successfully. - */ - toggleCol: function (n) { - if (g.colVisib[n]) { - // can hide if more than one column is visible - if (g.visibleHeadersCount > 1) { - $(g.t).find('tr').each(function () { - $(this).find('th.draggable:eq(' + n + '),' + - 'td:eq(' + (g.actionSpan + n) + ')') - .hide(); - }); - g.colVisib[n] = 0; - $(g.cList).find('.lDiv div:eq(' + n + ') input').prop('checked', false); - } else { - // cannot hide, force the checkbox to stay checked - $(g.cList).find('.lDiv div:eq(' + n + ') input').prop('checked', true); - return false; - } - } else { // column n is not visible - $(g.t).find('tr').each(function () { - $(this).find('th.draggable:eq(' + n + '),' + - 'td:eq(' + (g.actionSpan + n) + ')') - .show(); - }); - g.colVisib[n] = 1; - $(g.cList).find('.lDiv div:eq(' + n + ') input').prop('checked', true); - } - return true; - }, - - /** - * This must be called if toggleCol() returns is true. - * - * This function is separated from toggleCol because, sometimes, we want to toggle - * some columns together at one time and do just one adjustment after it, e.g. in showAllColumns(). - */ - afterToggleCol: function () { - // some adjustments after hiding column - g.reposRsz(); - g.reposDrop(); - g.sendColPrefs(); - - // check visible first row headers count - g.visibleHeadersCount = $(g.t).find('tr:first th.draggable:visible').length; - g.refreshRestoreButton(); - }, - - /** - * Show columns' visibility list. - * - * @param obj The drop down arrow of column visibility list - */ - showColList: function (obj) { - // only show when not resizing or reordering - if (!g.colRsz && !g.colReorder) { - var pos = $(obj).position(); - // check if the list position is too right - if (pos.left + $(g.cList).outerWidth(true) > $(document).width()) { - pos.left = $(document).width() - $(g.cList).outerWidth(true); - } - $(g.cList).css({ - left: pos.left, - top: pos.top + $(obj).outerHeight(true) - }) - .show(); - $(obj).addClass('coldrop-hover'); - } - }, - - /** - * Hide columns' visibility list. - */ - hideColList: function () { - $(g.cList).hide(); - $(g.cDrop).find('.coldrop-hover').removeClass('coldrop-hover'); - }, - - /** - * Reposition the column visibility drop-down arrow. - */ - reposDrop: function () { - var $th = $(t).find('th:not(.draggable)'); - for (var i = 0; i < $th.length; i++) { - var $cd = $(g.cDrop).find('div:eq(' + i + ')'); // column drop-down arrow - var pos = $($th[i]).position(); - $cd.css({ - left: pos.left + $($th[i]).width() - $cd.width(), - top: pos.top - }); - } - }, - - /** - * Show all hidden columns. - */ - showAllColumns: function () { - for (var i = 0; i < g.colVisib.length; i++) { - if (!g.colVisib[i]) { - g.toggleCol(i); - } - } - g.afterToggleCol(); - }, - - /** - * Show edit cell, if it can be shown - * - * @param cell <td> element to be edited - */ - showEditCell: function (cell) { - if ($(cell).is('.grid_edit') && - !g.colRsz && !g.colReorder) { - if (!g.isCellEditActive) { - var $cell = $(cell); - - if ('string' === $cell.attr('data-type') || - 'blob' === $cell.attr('data-type') || - 'json' === $cell.attr('data-type') - ) { - g.cEdit = g.cEditTextarea; - } else { - g.cEdit = g.cEditStd; - } - - // remove all edit area and hide it - $(g.cEdit).find('.edit_area').empty().hide(); - // reposition the cEdit element - $(g.cEdit).css({ - top: $cell.position().top, - left: $cell.position().left - }) - .show() - .find('.edit_box') - .css({ - width: $cell.outerWidth(), - height: $cell.outerHeight() - }); - // fill the cell edit with text from <td> - var value = Functions.getCellValue(cell); - if ($cell.attr('data-type') === 'json' && $cell.is('.truncated') === false) { - try { - value = JSON.stringify(JSON.parse(value), null, 4); - } catch (e) { - // Show as is - } - } - $(g.cEdit).find('.edit_box').val(value); - - g.currentEditCell = cell; - $(g.cEdit).find('.edit_box').trigger('focus'); - moveCursorToEnd($(g.cEdit).find('.edit_box')); - $(g.cEdit).find('*').prop('disabled', false); - } - } - - function moveCursorToEnd (input) { - var originalValue = input.val(); - var originallength = originalValue.length; - input.val(''); - input.trigger('blur').trigger('focus').val(originalValue); - input[0].setSelectionRange(originallength, originallength); - } - }, - - /** - * Remove edit cell and the edit area, if it is shown. - * - * @param force Optional, force to hide edit cell without saving edited field. - * @param data Optional, data from the POST AJAX request to save the edited field - * or just specify "true", if we want to replace the edited field with the new value. - * @param field Optional, the edited <td>. If not specified, the function will - * use currently edited <td> from g.currentEditCell. - * @param field Optional, this object contains a boolean named move (true, if called from move* functions) - * and a <td> to which the grid_edit should move - */ - hideEditCell: function (force, data, field, options) { - if (g.isCellEditActive && !force) { - // cell is being edited, save or post the edited data - if (options !== undefined) { - g.saveOrPostEditedCell(options); - } else { - g.saveOrPostEditedCell(); - } - return; - } - - // cancel any previous request - if (g.lastXHR !== null) { - g.lastXHR.abort(); - g.lastXHR = null; - } - - if (data) { - if (g.currentEditCell) { // save value of currently edited cell - // replace current edited field with the new value - var $thisField = $(g.currentEditCell); - var isNull = $thisField.data('value') === null; - if (isNull) { - $thisField.find('span').html('NULL'); - $thisField.addClass('null'); - } else { - $thisField.removeClass('null'); - var value = data.isNeedToRecheck - ? data.truncatableFieldValue - : $thisField.data('value'); - - // Truncates the text. - $thisField.removeClass('truncated'); - if (CommonParams.get('pftext') === 'P' && value.length > g.maxTruncatedLen) { - $thisField.addClass('truncated'); - value = value.substring(0, g.maxTruncatedLen) + '...'; - } - - // Add <br> before carriage return. - var newHtml = Functions.escapeHtml(value); - newHtml = newHtml.replace(/\n/g, '<br>\n'); - - // remove decimal places if column type not supported - if (($thisField.attr('data-decimals') === 0) && ($thisField.attr('data-type').indexOf('time') !== -1)) { - newHtml = newHtml.substring(0, newHtml.indexOf('.')); - } - - // remove addtional decimal places - if (($thisField.attr('data-decimals') > 0) && ($thisField.attr('data-type').indexOf('time') !== -1)) { - newHtml = newHtml.substring(0, newHtml.length - (6 - $thisField.attr('data-decimals'))); - } - - var selector = 'span'; - if ($thisField.hasClass('hex') && $thisField.find('a').length) { - selector = 'a'; - } - - // Updates the code keeping highlighting (if any). - var $target = $thisField.find(selector); - if (!Functions.updateCode($target, newHtml, value)) { - $target.html(newHtml); - } - } - if ($thisField.is('.bit')) { - $thisField.find('span').text($thisField.data('value')); - } - } - if (data.transformations !== undefined) { - $.each(data.transformations, function (cellIndex, value) { - var $thisField = $(g.t).find('.to_be_saved:eq(' + cellIndex + ')'); - $thisField.find('span').html(value); - }); - } - if (data.relations !== undefined) { - $.each(data.relations, function (cellIndex, value) { - var $thisField = $(g.t).find('.to_be_saved:eq(' + cellIndex + ')'); - $thisField.find('span').html(value); - }); - } - - // refresh the grid - g.reposRsz(); - g.reposDrop(); - } - - // hide the cell editing area - $(g.cEdit).hide(); - $(g.cEdit).find('.edit_box').trigger('blur'); - g.isCellEditActive = false; - g.currentEditCell = null; - // destroy datepicker in edit area, if exist - var $dp = $(g.cEdit).find('.hasDatepicker'); - if ($dp.length > 0) { - // eslint-disable-next-line no-underscore-dangle - $(document).on('mousedown', $.datepicker._checkExternalClick); - $dp.datepicker('destroy'); - // change the cursor in edit box back to normal - // (the cursor become a hand pointer when we add datepicker) - $(g.cEdit).find('.edit_box').css('cursor', 'inherit'); - } - }, - - /** - * Show drop-down edit area when edit cell is focused. - */ - showEditArea: function () { - if (!g.isCellEditActive) { // make sure the edit area has not been shown - g.isCellEditActive = true; - g.isEditCellTextEditable = false; - /** - * @var $td current edited cell - */ - var $td = $(g.currentEditCell); - /** - * @var $editArea the editing area - */ - var $editArea = $(g.cEdit).find('.edit_area'); - /** - * @var where_clause WHERE clause for the edited cell - */ - var whereClause = $td.parent('tr').find('.where_clause').val(); - /** - * @var field_name String containing the name of this field. - * @see Sql.getFieldName() - */ - var fieldName = Sql.getFieldName($(t), $td); - /** - * @var relation_curr_value String current value of the field (for fields that are foreign keyed). - */ - var relationCurrValue = $td.text(); - /** - * @var relation_key_or_display_column String relational key if in 'Relational display column' mode, - * relational display column if in 'Relational key' mode (for fields that are foreign keyed). - */ - var relationKeyOrDisplayColumn = $td.find('a').attr('title'); - /** - * @var curr_value String current value of the field (for fields that are of type enum or set). - */ - var currValue = $td.find('span').text(); - - // empty all edit area, then rebuild it based on $td classes - $editArea.empty(); - - // remember this instead of testing more than once - var isNull = $td.is('.null'); - - // add goto link, if this cell contains a link - if ($td.find('a').length > 0) { - var gotoLink = document.createElement('div'); - gotoLink.className = 'goto_link'; - $(gotoLink).append(g.gotoLinkText + ' ').append($td.find('a').clone()); - $editArea.append(gotoLink); - } - - g.wasEditedCellNull = false; - if ($td.is(':not(.not_null)')) { - // append a null checkbox - $editArea.append('<div class="null_div"><label>Null:<input type="checkbox"></label></div>'); - - var $checkbox = $editArea.find('.null_div input'); - // check if current <td> is NULL - if (isNull) { - $checkbox.prop('checked', true); - g.wasEditedCellNull = true; - } - - // if the select/editor is changed un-check the 'checkbox_null_<field_name>_<row_index>'. - if ($td.is('.enum, .set')) { - $editArea.on('change', 'select', function () { - $checkbox.prop('checked', false); - }); - } else if ($td.is('.relation')) { - $editArea.on('change', 'select', function () { - $checkbox.prop('checked', false); - }); - $editArea.on('click', '.browse_foreign', function () { - $checkbox.prop('checked', false); - }); - } else { - $(g.cEdit).on('keypress change paste', '.edit_box', function () { - $checkbox.prop('checked', false); - }); - // Capture ctrl+v (on IE and Chrome) - $(g.cEdit).on('keydown', '.edit_box', function (e) { - if (e.ctrlKey && e.which === 86) { - $checkbox.prop('checked', false); - } - }); - $editArea.on('keydown', 'textarea', function () { - $checkbox.prop('checked', false); - }); - } - // if some text is written in textbox automatically unmark the null checkbox and if it is emptied again mark the checkbox. - $(g.cEdit).find('.edit_box').on('input', function () { - if ($(g.cEdit).find('.edit_box').val() !== '') { - $checkbox.prop('checked', false); - } else { - $checkbox.prop('checked', true); - } - }); - // if null checkbox is clicked empty the corresponding select/editor. - $checkbox.on('click', function () { - if ($td.is('.enum')) { - $editArea.find('select').val(''); - } else if ($td.is('.set')) { - $editArea.find('select').find('option').each(function () { - var $option = $(this); - $option.prop('selected', false); - }); - } else if ($td.is('.relation')) { - // if the dropdown is there to select the foreign value - if ($editArea.find('select').length > 0) { - $editArea.find('select').val(''); - } - } else { - $editArea.find('textarea').val(''); - } - $(g.cEdit).find('.edit_box').val(''); - }); - } - - // reset the position of the edit_area div after closing datetime picker - $(g.cEdit).find('.edit_area').css({ 'top' :'0','position':'' }); - - var postParams; - if ($td.is('.relation')) { - // handle relations - $editArea.addClass('edit_area_loading'); - - // initialize the original data - $td.data('original_data', null); - - /** - * @var post_params Object containing parameters for the POST request - */ - postParams = { - 'ajax_request' : true, - 'get_relational_values' : true, - 'server' : g.server, - 'db' : g.db, - 'table' : g.table, - 'column' : fieldName, - 'curr_value' : relationCurrValue, - 'relation_key_or_display_column' : relationKeyOrDisplayColumn - }; - - g.lastXHR = $.post('sql.php', postParams, function (data) { - g.lastXHR = null; - $editArea.removeClass('edit_area_loading'); - if ($(data.dropdown).is('select')) { - // save original_data - var value = $(data.dropdown).val(); - $td.data('original_data', value); - // update the text input field, in case where the "Relational display column" is checked - $(g.cEdit).find('.edit_box').val(value); - } - - $editArea.append(data.dropdown); - $editArea.append('<div class="cell_edit_hint">' + g.cellEditHint + '</div>'); - - // for 'Browse foreign values' options, - // hide the value next to 'Browse foreign values' link - $editArea.find('span.curr_value').hide(); - // handle update for new values selected from new window - $editArea.find('span.curr_value').on('change', function () { - $(g.cEdit).find('.edit_box').val($(this).text()); - }); - }); // end $.post() - - $editArea.show(); - $editArea.on('change', 'select', function () { - $(g.cEdit).find('.edit_box').val($(this).val()); - }); - g.isEditCellTextEditable = true; - } else if ($td.is('.enum')) { - // handle enum fields - $editArea.addClass('edit_area_loading'); - - /** - * @var post_params Object containing parameters for the POST request - */ - postParams = { - 'ajax_request' : true, - 'get_enum_values' : true, - 'server' : g.server, - 'db' : g.db, - 'table' : g.table, - 'column' : fieldName, - 'curr_value' : currValue - }; - g.lastXHR = $.post('sql.php', postParams, function (data) { - g.lastXHR = null; - $editArea.removeClass('edit_area_loading'); - $editArea.append(data.dropdown); - $editArea.append('<div class="cell_edit_hint">' + g.cellEditHint + '</div>'); - }); // end $.post() - - $editArea.show(); - $editArea.on('change', 'select', function () { - $(g.cEdit).find('.edit_box').val($(this).val()); - }); - } else if ($td.is('.set')) { - // handle set fields - $editArea.addClass('edit_area_loading'); - - // if the data is truncated, get the full data - if ($td.is('.truncated')) { - postParams = { - 'ajax_request': true, - 'get_set_values': true, - 'server': g.server, - 'db': g.db, - 'table': g.table, - 'column': fieldName, - 'curr_value': currValue, - 'get_full_values': true, - 'where_clause': whereClause - }; - } else { - postParams = { - 'ajax_request': true, - 'get_set_values': true, - 'server': g.server, - 'db': g.db, - 'table': g.table, - 'column': fieldName, - 'curr_value': currValue - }; - } - - g.lastXHR = $.post('sql.php', postParams, function (data) { - g.lastXHR = null; - $editArea.removeClass('edit_area_loading'); - $editArea.append(data.select); - $td.data('original_data', $(data.select).val().join()); - $editArea.append('<div class="cell_edit_hint">' + g.cellEditHint + '</div>'); - }); // end $.post() - - $editArea.show(); - $editArea.on('change', 'select', function () { - $(g.cEdit).find('.edit_box').val($(this).val()); - }); - } else if ($td.is('.truncated, .transformed')) { - if ($td.is('.to_be_saved')) { // cell has been edited - var value = $td.data('value'); - $(g.cEdit).find('.edit_box').val(value); - $editArea.append('<textarea></textarea>'); - $editArea.find('textarea').val(value); - $editArea - .on('keyup', 'textarea', function () { - $(g.cEdit).find('.edit_box').val($(this).val()); - }); - $(g.cEdit).on('keyup', '.edit_box', function () { - $editArea.find('textarea').val($(this).val()); - }); - $editArea.append('<div class="cell_edit_hint">' + g.cellEditHint + '</div>'); - } else { - // handle truncated/transformed values values - $editArea.addClass('edit_area_loading'); - - // initialize the original data - $td.data('original_data', null); - - /** - * @var sql_query String containing the SQL query used to retrieve value of truncated/transformed data - */ - var sqlQuery = 'SELECT `' + fieldName + '` FROM `' + g.table + '` WHERE ' + whereClause; - - // Make the Ajax call and get the data, wrap it and insert it - g.lastXHR = $.post('sql.php', { - 'server' : g.server, - 'db' : g.db, - 'ajax_request' : true, - 'sql_query' : sqlQuery, - 'grid_edit' : true - }, function (data) { - g.lastXHR = null; - $editArea.removeClass('edit_area_loading'); - if (typeof data !== 'undefined' && data.success === true) { - if ($td.attr('data-type') === 'json') { - try { - data.value = JSON.stringify(JSON.parse(data.value), null, 4); - } catch (e) { - // Show as is - } - } - $td.data('original_data', data.value); - $(g.cEdit).find('.edit_box').val(data.value); - } else { - Functions.ajaxShowMessage(data.error, false); - } - }); // end $.post() - } - g.isEditCellTextEditable = true; - } else if ($td.is('.timefield, .datefield, .datetimefield, .timestampfield')) { - var $inputField = $(g.cEdit).find('.edit_box'); - - // remember current datetime value in $input_field, if it is not null - var datetimeValue = !isNull ? $inputField.val() : ''; - - var showMillisec = false; - var showMicrosec = false; - var timeFormat = 'HH:mm:ss'; - // check for decimal places of seconds - if (($td.attr('data-decimals') > 0) && ($td.attr('data-type').indexOf('time') !== -1)) { - if (datetimeValue && datetimeValue.indexOf('.') === false) { - datetimeValue += '.'; - } - if ($td.attr('data-decimals') > 3) { - showMillisec = true; - showMicrosec = true; - timeFormat = 'HH:mm:ss.lc'; - - if (datetimeValue) { - datetimeValue += '000000'; - datetimeValue = datetimeValue.substring(0, datetimeValue.indexOf('.') + 7); - $inputField.val(datetimeValue); - } - } else { - showMillisec = true; - timeFormat = 'HH:mm:ss.l'; - - if (datetimeValue) { - datetimeValue += '000'; - datetimeValue = datetimeValue.substring(0, datetimeValue.indexOf('.') + 4); - $inputField.val(datetimeValue); - } - } - } - - // add datetime picker - Functions.addDatepicker($inputField, $td.attr('data-type'), { - showMillisec: showMillisec, - showMicrosec: showMicrosec, - timeFormat: timeFormat - }); - - $inputField.on('keyup', function (e) { - if (e.which === 13) { - // post on pressing "Enter" - e.preventDefault(); - e.stopPropagation(); - g.saveOrPostEditedCell(); - } else if (e.which !== 27) { - Functions.toggleDatepickerIfInvalid($td, $inputField); - } - }); - - $inputField.datepicker('show'); - Functions.toggleDatepickerIfInvalid($td, $inputField); - - // unbind the mousedown event to prevent the problem of - // datepicker getting closed, needs to be checked for any - // change in names when updating - // eslint-disable-next-line no-underscore-dangle - $(document).off('mousedown', $.datepicker._checkExternalClick); - - // move ui-datepicker-div inside cEdit div - var datepickerDiv = $('#ui-datepicker-div'); - datepickerDiv.css({ 'top': 0, 'left': 0, 'position': 'relative' }); - $(g.cEdit).append(datepickerDiv); - - // cancel any click on the datepicker element - $editArea.find('> *').on('click', function (e) { - e.stopPropagation(); - }); - - g.isEditCellTextEditable = true; - } else { - g.isEditCellTextEditable = true; - // only append edit area hint if there is a null checkbox - if ($editArea.children().length > 0) { - $editArea.append('<div class="cell_edit_hint">' + g.cellEditHint + '</div>'); - } - } - if ($editArea.children().length > 0) { - $editArea.show(); - } - } - }, - - /** - * Post the content of edited cell. - * - * @param field Optional, this object contains a boolean named move (true, if called from move* functions) - * and a <td> to which the grid_edit should move - */ - postEditedCell: function (options) { - if (g.isSaving) { - return; - } - g.isSaving = true; - /** - * @var relation_fields Array containing the name/value pairs of relational fields - */ - var relationFields = {}; - /** - * @var relational_display string 'K' if relational key, 'D' if relational display column - */ - var relationalDisplay = $(g.o).find('input[name=relational_display]:checked').val(); - /** - * @var transform_fields Array containing the name/value pairs for transformed fields - */ - var transformFields = {}; - /** - * @var transformation_fields Boolean, if there are any transformed fields in the edited cells - */ - var transformationFields = false; - /** - * @var full_sql_query String containing the complete SQL query to update this table - */ - var fullSqlQuery = ''; - /** - * @var rel_fields_list String, url encoded representation of {@link relations_fields} - */ - var relFieldsList = ''; - /** - * @var transform_fields_list String, url encoded representation of {@link transformFields} - */ - var transformFieldsList = ''; - /** - * @var where_clause Array containing where clause for updated fields - */ - var fullWhereClause = []; - /** - * @var is_unique Boolean, whether the rows in this table is unique or not - */ - var isUnique = $(g.t).find('td.edit_row_anchor').is('.nonunique') ? 0 : 1; - /** - * multi edit variables - */ - var multiEditFieldsName = []; - var multiEditFieldsType = []; - var multiEditFields = []; - var multiEditFieldsNull = []; - - // alert user if edited table is not unique - if (!isUnique) { - alert(g.alertNonUnique); - } - - // loop each edited row - $(g.t).find('td.to_be_saved').parents('tr').each(function () { - var $tr = $(this); - var whereClause = $tr.find('.where_clause').val(); - if (typeof whereClause === 'undefined') { - whereClause = ''; - } - fullWhereClause.push(whereClause); - var conditionArray = JSON.parse($tr.find('.condition_array').val()); - - /** - * multi edit variables, for current row - * @TODO array indices are still not correct, they should be md5 of field's name - */ - var fieldsName = []; - var fieldsType = []; - var fields = []; - var fieldsNull = []; - - // loop each edited cell in a row - $tr.find('.to_be_saved').each(function () { - /** - * @var $this_field Object referring to the td that is being edited - */ - var $thisField = $(this); - - /** - * @var field_name String containing the name of this field. - * @see Sql.getFieldName() - */ - var fieldName = Sql.getFieldName($(g.t), $thisField); - - /** - * @var this_field_params Array temporary storage for the name/value of current field - */ - var thisFieldParams = {}; - - if ($thisField.is('.transformed')) { - transformationFields = true; - } - thisFieldParams[fieldName] = $thisField.data('value'); - - /** - * @var is_null String capturing whether 'checkbox_null_<field_name>_<row_index>' is checked. - */ - var isNull = thisFieldParams[fieldName] === null; - - fieldsName.push(fieldName); - - if (isNull) { - fieldsNull.push('on'); - fields.push(''); - } else { - if ($thisField.is('.bit')) { - fieldsType.push('bit'); - } else if ($thisField.hasClass('hex')) { - fieldsType.push('hex'); - } - fieldsNull.push(''); - // Convert \n to \r\n to be consistent with form submitted value. - // The internal browser representation has to be just \n - // while form submitted value \r\n, see specification: - // https://www.w3.org/TR/html5/forms.html#the-textarea-element - fields.push($thisField.data('value').replace(/\n/g, '\r\n')); - - var cellIndex = $thisField.index('.to_be_saved'); - if ($thisField.is(':not(.relation, .enum, .set, .bit)')) { - if ($thisField.is('.transformed')) { - transformFields[cellIndex] = {}; - $.extend(transformFields[cellIndex], thisFieldParams); - } - } else if ($thisField.is('.relation')) { - relationFields[cellIndex] = {}; - $.extend(relationFields[cellIndex], thisFieldParams); - } - } - // check if edited field appears in WHERE clause - if (whereClause.indexOf(Sql.urlEncode(fieldName)) > -1) { - var fieldStr = '`' + g.table + '`.' + '`' + fieldName + '`'; - for (var field in conditionArray) { - if (field.indexOf(fieldStr) > -1) { - conditionArray[field] = isNull ? 'IS NULL' : '= \'' + thisFieldParams[fieldName].replace(/'/g, '\'\'') + '\''; - break; - } - } - } - }); // end of loop for every edited cells in a row - - // save new_clause - var newClause = ''; - for (var field in conditionArray) { - newClause += field + ' ' + conditionArray[field] + ' AND '; - } - newClause = newClause.substring(0, newClause.length - 5); // remove the last AND - $tr.data('new_clause', newClause); - // save condition_array - $tr.find('.condition_array').val(JSON.stringify(conditionArray)); - - multiEditFieldsName.push(fieldsName); - multiEditFieldsType.push(fieldsType); - multiEditFields.push(fields); - multiEditFieldsNull.push(fieldsNull); - }); // end of loop for every edited rows - - relFieldsList = $.param(relationFields); - transformFieldsList = $.param(transformFields); - - // Make the Ajax post after setting all parameters - /** - * @var post_params Object containing parameters for the POST request - */ - var postParams = { 'ajax_request' : true, - 'sql_query' : fullSqlQuery, - 'server' : g.server, - 'db' : g.db, - 'table' : g.table, - 'clause_is_unique' : isUnique, - 'where_clause' : fullWhereClause, - 'fields[multi_edit]' : multiEditFields, - 'fields_name[multi_edit]' : multiEditFieldsName, - 'fields_type[multi_edit]' : multiEditFieldsType, - 'fields_null[multi_edit]' : multiEditFieldsNull, - 'rel_fields_list' : relFieldsList, - 'do_transformations' : transformationFields, - 'transform_fields_list' : transformFieldsList, - 'relational_display' : relationalDisplay, - 'goto' : 'sql.php', - 'submit_type' : 'save' - }; - - if (!g.saveCellsAtOnce) { - $(g.cEdit).find('*').prop('disabled', true); - $(g.cEdit).find('.edit_box').addClass('edit_box_posting'); - } else { - $(g.o).find('div.save_edited').addClass('saving_edited_data') - .find('input').prop('disabled', true); // disable the save button - } - - $.ajax({ - type: 'POST', - url: 'tbl_replace.php', - data: postParams, - success: - function (data) { - g.isSaving = false; - if (!g.saveCellsAtOnce) { - $(g.cEdit).find('*').prop('disabled', false); - $(g.cEdit).find('.edit_box').removeClass('edit_box_posting'); - } else { - $(g.o).find('div.save_edited').removeClass('saving_edited_data') - .find('input').prop('disabled', false); // enable the save button back - } - if (typeof data !== 'undefined' && data.success === true) { - if (typeof options === 'undefined' || ! options.move) { - Functions.ajaxShowMessage(data.message); - } - - // update where_clause related data in each edited row - $(g.t).find('td.to_be_saved').parents('tr').each(function () { - var newClause = $(this).data('new_clause'); - var $whereClause = $(this).find('.where_clause'); - var oldClause = $whereClause.val(); - var decodedOldClause = oldClause; - var decodedNewClause = newClause; - - $whereClause.val(newClause); - // update Edit, Copy, and Delete links also - $(this).find('a').each(function () { - $(this).attr('href', $(this).attr('href').replace(oldClause, newClause)); - // update delete confirmation in Delete link - if ($(this).attr('href').indexOf('DELETE') > -1) { - $(this).removeAttr('onclick') - .off('click') - .on('click', function () { - return Functions.confirmLink(this, 'DELETE FROM `' + g.db + '`.`' + g.table + '` WHERE ' + - decodedNewClause + (isUnique ? '' : ' LIMIT 1')); - }); - } - }); - // update the multi edit checkboxes - $(this).find('input[type=checkbox]').each(function () { - var $checkbox = $(this); - var checkboxName = $checkbox.attr('name'); - var checkboxValue = $checkbox.val(); - - $checkbox.attr('name', checkboxName.replace(oldClause, newClause)); - $checkbox.val(checkboxValue.replace(decodedOldClause, decodedNewClause)); - }); - }); - // update the display of executed SQL query command - if (typeof data.sql_query !== 'undefined') { - // extract query box - var $resultQuery = $($.parseHTML(data.sql_query)); - var sqlOuter = $resultQuery.find('.sqlOuter').wrap('<p>').parent().html(); - var tools = $resultQuery.find('.tools').wrap('<p>').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 $existingQuery = $(g.o).find('.result_query'); - // If two query box exists update query in second else add a second box - if ($existingQuery.find('div.sqlOuter').length > 1) { - $existingQuery.children(':nth-child(4)').remove(); - $existingQuery.children(':nth-child(4)').remove(); - $existingQuery.append(sqlOuter + tools); - } else { - $existingQuery.append(sqlOuter + tools); - } - Functions.highlightSql($existingQuery); - } - } - // 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 { - Functions.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 $thisField = $(g.currentEditCell); - var $testElement = ''; // to test the presence of a element - - var needToPost = false; - - /** - * @var field_name String containing the name of this field. - * @see Sql.getFieldName() - */ - var fieldName = Sql.getFieldName($(g.t), $thisField); - - /** - * @var this_field_params Array temporary storage for the name/value of current field - */ - var thisFieldParams = {}; - - /** - * @var is_null String capturing whether 'checkbox_null_<field_name>_<row_index>' is checked. - */ - var isNull = $(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 - needToPost = false; - } else if (isNull) { - if (!g.wasEditedCellNull) { - thisFieldParams[fieldName] = null; - needToPost = true; - } - } else { - if ($thisField.is('.bit')) { - thisFieldParams[fieldName] = $(g.cEdit).find('.edit_box').val(); - } else if ($thisField.is('.set')) { - $testElement = $(g.cEdit).find('select'); - thisFieldParams[fieldName] = $testElement.map(function () { - return $(this).val(); - }).get().join(','); - } else if ($thisField.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 - thisFieldParams[fieldName] = $(g.cEdit).find('.edit_box').val(); - } else if ($thisField.hasClass('hex')) { - if ($(g.cEdit).find('.edit_box').val().match(/^(0x)?[a-f0-9]*$/i) !== null) { - thisFieldParams[fieldName] = $(g.cEdit).find('.edit_box').val(); - } else { - var hexError = '<div class="error">' + Messages.strEnterValidHex + '</div>'; - Functions.ajaxShowMessage(hexError, false); - thisFieldParams[fieldName] = Functions.getCellValue(g.currentEditCell); - } - } else { - thisFieldParams[fieldName] = $(g.cEdit).find('.edit_box').val(); - } - if (g.wasEditedCellNull || thisFieldParams[fieldName] !== Functions.getCellValue(g.currentEditCell)) { - needToPost = true; - } - } - - if (needToPost) { - $(g.currentEditCell).addClass('to_be_saved') - .data('value', thisFieldParams[fieldName]); - if (g.saveCellsAtOnce) { - $(g.o).find('div.save_edited').show(); - } - g.isCellEdited = true; - } - - return needToPost; - }, - - /** - * 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 <td> 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') - .on('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 = Messages.strColOrderHint; - - // get data columns in the first row of the table - var $firstRowCols = $(g.t).find('tr:first th.draggable'); - - // initialize column order - var $colOrder = $(g.o).find('.col_order'); // check if column order is passed from PHP - var i; - if ($colOrder.length > 0) { - g.colOrder = $colOrder.val().split(','); - for (i = 0; i < g.colOrder.length; i++) { - g.colOrder[i] = parseInt(g.colOrder[i], 10); - } - } else { - g.colOrder = []; - for (i = 0; i < $firstRowCols.length; i++) { - g.colOrder.push(i); - } - } - - // register events - $(g.t).find('th.draggable') - .on('mousedown', function (e) { - $(g.o).addClass('turnOffSelect'); - if (g.visibleHeadersCount > 1) { - g.dragStartReorder(e, this); - } - }) - .on('mouseenter', function () { - if (g.visibleHeadersCount > 1) { - $(this).css('cursor', 'move'); - } else { - $(this).css('cursor', 'inherit'); - } - }) - .on('mouseleave', function () { - g.showReorderHint = false; - $(this).tooltip('option', { - content: g.updateHint() - }); - }) - .on('dblclick', function (e) { - e.preventDefault(); - $('<div></div>') - .prop('title', Messages.strColNameCopyTitle) - .addClass('modal-copy') - .text(Messages.strColNameCopyText) - .append( - $('<input>') - .prop('readonly', true) - .val($(this).data('column')) - ) - .dialog({ - resizable: false, - modal: true - }) - .find('input').trigger('focus').trigger('select'); - }); - $(g.t).find('th.draggable a') - .on('dblclick', function (e) { - e.stopPropagation(); - }); - // restore column order when the restore button is clicked - $(g.o).find('div.restore_column').on('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 = 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 $colVisib = $(g.o).find('.col_visib'); // check if column visibility is passed from PHP - if ($colVisib.length > 0) { - g.colVisib = $colVisib.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)'); - Functions.tooltip( - $colVisibTh, - 'th', - Messages.strColVisibHint - ); - - // create column visibility drop-down arrow(s) - $colVisibTh.each(function () { - var cd = document.createElement('div'); // column drop-down arrow - $(cd).addClass('coldrop') - .on('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 = '<div class="lDiv"></div>'; - 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('<input type="checkbox" ' + (g.colVisib[i] ? 'checked="checked" ' : '') + '>'); - $listDiv.append(listElmt); - // add event on click - $(listElmt).on('click', tempClick); - } - // add "show all column" button - var showAll = document.createElement('div'); - $(showAll).addClass('showAllColBtn') - .text(g.showAllColText); - $(g.cList).append(showAll); - $(showAll).on('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).on('click', function () { - g.showAllColumns(); - }); - } - } - - // hide column visibility list if we move outside the list - $(g.t).find('td, th.draggable').on('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 $thisField = $(g.currentEditCell); - var fieldName = Sql.getFieldName($(g.t), $thisField); - - var whereClause = $thisField.parents('tr').first().find('.where_clause').val(); - if (typeof whereClause === 'undefined') { - whereClause = ''; - } - var found = false; - var $prevRow; - - $thisField.parents('tr').first().parents('tbody').children().each(function () { - if ($(this).find('.where_clause').val() === whereClause) { - found = true; - } - if (!found) { - $prevRow = $(this); - } - }); - - var newCell; - - if (found && $prevRow) { - $prevRow.children('td').each(function () { - if (Sql.getFieldName($(g.t), $(this)) === fieldName) { - newCell = this; - } - }); - } - - if (newCell) { - g.hideEditCell(false, false, false, { move : true, cell : newCell }); - } - }, - - /** - * Move currently Editing Cell to Down - */ - moveDown: function (e) { - e.preventDefault(); - - var $thisField = $(g.currentEditCell); - var fieldName = Sql.getFieldName($(g.t), $thisField); - - var whereClause = $thisField.parents('tr').first().find('.where_clause').val(); - if (typeof whereClause === 'undefined') { - whereClause = ''; - } - var found = false; - var $nextRow; - var j = 0; - var nextRowFound = false; - $thisField.parents('tr').first().parents('tbody').children().each(function () { - if ($(this).find('.where_clause').val() === whereClause) { - found = true; - } - if (found) { - if (j >= 1 && ! nextRowFound) { - $nextRow = $(this); - nextRowFound = true; - } else { - j++; - } - } - }); - - var newCell; - if (found && $nextRow) { - $nextRow.children('td').each(function () { - if (Sql.getFieldName($(g.t), $(this)) === fieldName) { - newCell = this; - } - }); - } - - if (newCell) { - g.hideEditCell(false, false, false, { move : true, cell : newCell }); - } - }, - - /** - * Move currently Editing Cell to Left - */ - moveLeft: function (e) { - e.preventDefault(); - - var $thisField = $(g.currentEditCell); - var fieldName = Sql.getFieldName($(g.t), $thisField); - - var whereClause = $thisField.parents('tr').first().find('.where_clause').val(); - if (typeof whereClause === 'undefined') { - whereClause = ''; - } - var found = false; - var $foundRow; - $thisField.parents('tr').first().parents('tbody').children().each(function () { - if ($(this).find('.where_clause').val() === whereClause) { - found = true; - $foundRow = $(this); - } - }); - - var leftCell; - var cellFound = false; - if (found) { - $foundRow.children('td.grid_edit').each(function () { - if (Sql.getFieldName($(g.t), $(this)) === fieldName) { - cellFound = true; - } - if (!cellFound) { - leftCell = this; - } - }); - } - - if (leftCell) { - g.hideEditCell(false, false, false, { move : true, cell : leftCell }); - } - }, - - /** - * Move currently Editing Cell to Right - */ - moveRight: function (e) { - e.preventDefault(); - - var $thisField = $(g.currentEditCell); - var fieldName = Sql.getFieldName($(g.t), $thisField); - - var whereClause = $thisField.parents('tr').first().find('.where_clause').val(); - if (typeof whereClause === 'undefined') { - whereClause = ''; - } - var found = false; - var $foundRow; - var j = 0; - $thisField.parents('tr').first().parents('tbody').children().each(function () { - if ($(this).find('.where_clause').val() === whereClause) { - found = true; - $foundRow = $(this); - } - }); - - var rightCell; - var cellFound = false; - var nextCellFound = false; - if (found) { - $foundRow.children('td.grid_edit').each(function () { - if (Sql.getFieldName($(g.t), $(this)) === fieldName) { - cellFound = true; - } - if (cellFound) { - if (j >= 1 && ! nextCellFound) { - rightCell = this; - nextCellFound = true; - } else { - j++; - } - } - }); - } - - if (rightCell) { - g.hideEditCell(false, false, false, { move : true, cell : rightCell }); - } - }, - - /** - * 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('<input class="edit_box" rows="1"><div class="edit_area"></div>'); - $(g.cEditStd).hide(); - - // adjust g.cEdit - g.cEditTextarea.className = 'cEdit'; - $(g.cEditTextarea).html('<textarea class="edit_box" rows="1"></textarea><div class="edit_area"></div>'); - $(g.cEditTextarea).hide(); - - // assign cell editing hint - g.cellEditHint = Messages.strCellEditHint; - g.saveCellWarning = Messages.strSaveCellWarning; - g.alertNonUnique = Messages.strAlertNonUnique; - g.gotoLinkText = Messages.strGoToLink; - - // initialize cell editing configuration - g.saveCellsAtOnce = $(g.o).find('.save_cells_at_once').val(); - g.maxTruncatedLen = CommonParams.get('LimitChars'); - - // register events - $(g.t).find('td.data.click1') - .on('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') - .on('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); - } - } - }) - .on('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').on('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).on('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').on('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).on('keydown', function (e) { - if (!g.isEditCellTextEditable) { - // prevent text editing - e.preventDefault(); - } - }); - $('html').on('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(); - } - }).on('keydown', function (e) { - if (e.which === 27 && g.isCellEditActive) { - // cancel on pressing "Esc" - g.hideEditCell(true); - } - }); - $(g.o).find('div.save_edited').on('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 (Messages.strGridEditFeatureHint !== undefined) { - Functions.tooltip( - $(g.t).find('.edit_row_anchor a'), - 'a', - 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 '<span title="' + Messages.strOriginalLength + ' ' + - $(this).data('originallength') + '"></span>'; - }); - - // wrap remaining cells, except actions cell, with span - $(t).find('th, td:not(:has(span))') - .wrapInner('<span></span>'); - - // 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 = Messages.strSortHint; - g.strMultiSortHint = Messages.strMultiSortHint; - g.markHint = Messages.strColMarkHint; - g.copyHint = Messages.strColNameCopyHint; - - // assign common hidden inputs - var $commonHiddenInputs = $(g.o).find('div.common_hidden_inputs'); - g.server = $commonHiddenInputs.find('input[name=server]').val(); - g.db = $commonHiddenInputs.find('input[name=db]').val(); - g.table = $commonHiddenInputs.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 - if (isResizeEnabled) { - g.initColResize(); - } - // disable reordering for result from EXPLAIN or SHOW syntax, which do not have a table navigation panel - if (isReorderEnabled && - $(g.o).find('table.navigation').length > 0) { - g.initColReorder(); - } - if (isVisibEnabled) { - g.initColVisib(); - } - // make sure we have the ajax class - if (isGridEditEnabled && - $(t).is('.ajax')) { - g.initGridEdit(); - } - - // create tooltip for each <th> with draggable class - Functions.tooltip( - $(t).find('th.draggable'), - 'th', - g.updateHint() - ); - - // register events for hint tooltip (anchors inside draggable th) - $(t).find('th.draggable a') - .on('mouseenter', function () { - g.showSortHint = true; - g.showMultiSortHint = true; - $(t).find('th.draggable').tooltip('option', { - content: g.updateHint() - }); - }) - .on('mouseleave', function () { - g.showSortHint = false; - g.showMultiSortHint = false; - $(t).find('th.draggable').tooltip('option', { - content: g.updateHint() - }); - }); - - // register events for dragging-related feature - if (isResizeEnabled || isReorderEnabled) { - $(document).on('mousemove', function (e) { - g.dragMove(e); - }); - $(document).on('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 isMsie = navigator.userAgent.indexOf('MSIE') > -1 || !!window.navigator.userAgent.match(/Trident.*rv:11\./); - var isFirefox = navigator.userAgent.indexOf('Firefox') > -1; - var isSafari = navigator.userAgent.indexOf('Safari') > -1; - var isOpera = navigator.userAgent.indexOf('Presto') > -1; - if (prevent) { - return this.each(function () { - if (isMsie || isSafari) { - $(this).on('selectstart', false); - } else if (isFirefox) { - $(this).css('MozUserSelect', 'none'); - $('body').trigger('focus'); - } else if (isOpera) { - $(this).on('mousedown', false); - } else { - $(this).attr('unselectable', 'on'); - } - }); - } else { - return this.each(function () { - if (isMsie || isSafari) { - $(this).off('selectstart'); - } else if (isFirefox) { - $(this).css('MozUserSelect', 'inherit'); - } else if (isOpera) { - $(this).off('mousedown'); - } else { - $(this).removeAttr('unselectable'); - } - }); - } - }; // end noSelect -}(jQuery)); |
