diff --git a/Documentation.html b/Documentation.html
index 72387ab63b..2fdf4f5fee 100644
--- a/Documentation.html
+++ b/Documentation.html
@@ -1373,6 +1373,9 @@ CREATE DATABASE,ALTER DATABASE,DROP DATABASE
main panel's list (except on the Export page). This limit is also enforced in the navigation panel
when in Light mode.
+
$cfg['ShowHint'] boolean
+
Whether to show the hints or not (for example, hints when hovering table header)
+
$cfg['MaxCharactersInDisplayedSQL'] integer
The maximum number of characters when a SQL query is displayed. The
default limit of 1000 should be correct to avoid the display of tons
@@ -1961,7 +1964,7 @@ $cfg['TrustedProxies'] =
$cfg['RowActionLinks'] string
-
Defines the place where table row links (Edit, Inline edit, Copy,
+
Defines the place where table row links (Edit, Copy,
Delete) would be put when tables contents are displayed (you may
have them displayed at the left side, right side, both sides or nowhere).
"left" and "right" are parsed as "top"
@@ -2143,6 +2146,11 @@ setfacl -d -m "g:www-data:rwx" tmp
identify what they mean.
+
$cfg['SaveCellsAtOnce'] boolean
+
+ Defines whether or not to save all edited cells at once in browse-mode.
+
+
$cfg['ShowDisplayDirection'] boolean
Defines whether or not type display direction option is shown
diff --git a/js/db_search.js b/js/db_search.js
index 3e2eeb40a7..aef5047be2 100644
--- a/js/db_search.js
+++ b/js/db_search.js
@@ -32,7 +32,6 @@ function loadResult(result_path , table_name , link , ajaxEnable)
// we assign it manually from #table-link
window.parent.table = $('#table-link').text().trim();
- appendInlineAnchor();
$('#table_results').makegrid();
}).show();
}
diff --git a/js/functions.js b/js/functions.js
index b16cf80c40..4447a4b584 100644
--- a/js/functions.js
+++ b/js/functions.js
@@ -3078,6 +3078,9 @@ $(document).ready(function() {
*/
function PMA_createqTip($elements, content, options)
{
+ if ($('#no_hint').length > 0) {
+ return;
+ }
var o = {
content: content,
style: {
@@ -3112,6 +3115,21 @@ function PMA_createqTip($elements, content, options)
$elements.qtip($.extend(true, o, options));
}
+/**
+ * Return value of a cell in a table.
+ */
+function PMA_getCellValue(td) {
+ if ($(td).is('.null')) {
+ return '';
+ } else if (! $(td).is('.to_be_saved') && $(td).data('original_data')) {
+ return $(td).data('original_data');
+ } else if ($(td).is(':not(.transformed, .relation, .enum, .set, .null)')) {
+ return unescape($(td).find('span').html()).replace(/ /g, "\n");
+ } else {
+ return $(td).text();
+ }
+}
+
$(document).ready(function() {
/**
* Theme selector.
diff --git a/js/jquery/jquery.qtip-1.0.0-rc3.js b/js/jquery/jquery.qtip-1.0.0-rc3.js
index 5b9c7e3064..4b01d9dbca 100644
--- a/js/jquery/jquery.qtip-1.0.0-rc3.js
+++ b/js/jquery/jquery.qtip-1.0.0-rc3.js
@@ -633,6 +633,7 @@
{
// Set width to auto initally to determine new width and hide other elements
self.elements.tooltip.css({ width: 'auto' });
+ self.elements.wrapper.css({ width: 'auto' });
hidden.hide();
// Set position and zoom to defaults to prevent IE hasLayout bug
@@ -2146,4 +2147,4 @@
classes: { tooltip: 'qtip-blue' }
}
};
-})(jQuery);
\ No newline at end of file
+})(jQuery);
diff --git a/js/makegrid.js b/js/makegrid.js
index 13fcc37a4c..91834ac381 100644
--- a/js/makegrid.js
+++ b/js/makegrid.js
@@ -21,7 +21,27 @@
showColVisibHint: false,
showAllColText: '', // string, text for "show all" button under column visibility list
visibleHeadersCount: 0, // number of visible data headers
-
+ 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
that currently being edited
+ inEditMode: false, // true if grid is in edit mode
+ cellEditHint: '', // hint shown when doing grid edit
+ gotoLinkText: 'Go to link', // "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
dragStartRsz: function(e, obj) { // start column resize
var n = $(this.cRsz).find('div').index(obj);
@@ -34,6 +54,9 @@
};
$('body').css('cursor', 'col-resize');
$('body').noSelect();
+ if (g.isCellEditActive) {
+ g.hideEditCell();
+ }
},
dragStartMove: function(e, obj) { // start column move
@@ -65,6 +88,9 @@
this.qtip.hide();
$('body').css('cursor', 'move');
$('body').noSelect();
+ if (g.isCellEditActive) {
+ g.hideEditCell();
+ }
},
dragMove: function(e) {
@@ -146,7 +172,6 @@
this.colMov = false;
}
- $('body').css('cursor', 'default');
$('body').noSelect(false);
},
@@ -266,10 +291,10 @@
sendColPrefs: function() {
$.post('sql.php', {
ajax_request: true,
- db: window.parent.db,
- table: window.parent.table,
- token: window.parent.token,
- server: window.parent.server,
+ db: g.db,
+ table: g.table,
+ token: g.token,
+ server: g.server,
set_col_prefs: true,
col_order: this.colOrder.toString(),
col_visib: this.colVisib.toString(),
@@ -438,6 +463,784 @@
}
}
this.afterToggleCol();
+ },
+
+ /**
+ * Show edit cell, if it can be shown or it is forced.
+ */
+ showEditCell: function(cell, force) {
+ if ($(cell).is('.grid_edit') &&
+ !g.colRsz && !g.colMov)
+ {
+ if (!g.isCellEditActive || force) {
+ $cell = $(cell);
+ // 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('input')
+ .css({
+ width: $cell.outerWidth(),
+ height: $cell.outerHeight()
+ });
+ // fill the cell edit with text from
, if it is not null
+ var value = $cell.is(':not(.null)') ? PMA_getCellValue(cell) : '';
+ $(g.cEdit).find('input')
+ .val(value);
+
+ g.currentEditCell = cell;
+ $(g.cEdit).find('input[type=text]').focus();
+ $(g.cEdit).find('*').removeAttr('disabled');
+ }
+ } else {
+ g.hideEditCell();
+ }
+ },
+
+ /**
+ * 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
. If not specified, the function will
+ * use currently edited
from g.currentEditCell.
+ */
+ hideEditCell: function(force, data, field) {
+ if (g.isCellEditActive && !force) {
+ // cell is being edited, post the edited data
+ 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 $this_field = $(g.currentEditCell);
+ var new_html = $this_field.data('value');
+ var is_null = $this_field.data('value') == null;
+ if (is_null) {
+ $this_field.find('span').html('NULL');
+ $this_field.addClass('null');
+ } else {
+ $this_field.removeClass('null');
+ if ($this_field.is('.truncated')) {
+ if (new_html.length > g.maxTruncatedLen) {
+ new_html = new_html.substring(0, g.maxTruncatedLen) + '...';
+ }
+ }
+ // replace '\n' with
+ new_html = new_html.replace(/\n/g, ' ');
+ $this_field.find('span').html(new_html);
+ }
+ }
+ if (data.transformations != undefined) {
+ $.each(data.transformations, function(cell_index, value) {
+ var $this_field = $(g.t).find('.to_be_saved:eq(' + cell_index + ')');
+ $this_field.find('span').html(value);
+ });
+ }
+ if (data.relations != undefined) {
+ $.each(data.relations, function(cell_index, value) {
+ var $this_field = $(g.t).find('.to_be_saved:eq(' + cell_index + ')');
+ $this_field.find('span').html(value);
+ });
+ }
+
+ // refresh the grid
+ this.reposRsz();
+ this.reposDrop();
+ }
+
+ // hide the cell editing area
+ $(g.cEdit).hide();
+ $(g.cEdit).find('input[type=text]').blur();
+ g.isCellEditActive = false;
+ g.currentEditCell = null;
+ },
+
+ /**
+ * Show drop-down edit area when edit cell is clicked.
+ */
+ showEditArea: function() {
+ if (!this.isCellEditActive) { // make sure we don't have focus on other edit cell
+ g.isCellEditActive = true;
+ g.isEditCellTextEditable = false;
+ var $td = $(g.currentEditCell);
+ var $editArea = $(this.cEdit).find('.edit_area');
+ var where_clause = $td.parent('tr').find('.where_clause').val();
+ /**
+ * @var field_name String containing the name of this field.
+ * @see getFieldName()
+ */
+ var field_name = getFieldName($td);
+ /**
+ * @var relation_curr_value String current value of the field (for fields that are foreign keyed).
+ */
+ var relation_curr_value = $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 relation_key_or_display_column = $td.find('a').attr('title');
+ /**
+ * @var curr_value String current value of the field (for fields that are of type enum or set).
+ */
+ var curr_value = $td.find('span').text();
+
+ // empty all edit area, then rebuild it based on $td classes
+ $editArea.empty();
+
+ // 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('
Null :
');
+ var $checkbox = $editArea.find('.null_div input');
+ // check if current
is NULL
+ if ($td.is('.null')) {
+ $checkbox.attr('checked', true);
+ g.wasEditedCellNull = true;
+ }
+
+ // if the select/editor is changed un-check the 'checkbox_null__'.
+ if ($td.is('.enum, .set')) {
+ $editArea.find('select').live('change', function(e) {
+ $checkbox.attr('checked', false);
+ })
+ } else if ($td.is('.relation')) {
+ $editArea.find('select').live('change', function(e) {
+ $checkbox.attr('checked', false);
+ })
+ $editArea.find('.browse_foreign').live('click', function(e) {
+ $checkbox.attr('checked', false);
+ })
+ } else {
+ $(g.cEdit).find('input[type=text]').live('change', function(e) {
+ $checkbox.attr('checked', false);
+ })
+ $editArea.find('textarea').live('keydown', function(e) {
+ $checkbox.attr('checked', false);
+ })
+ }
+
+ // if 'checkbox_null__' is clicked empty the corresponding select/editor.
+ $checkbox.click(function(e) {
+ if ($td.is('.enum')) {
+ $editArea.find('select').attr('value', '');
+ } else if ($td.is('.set')) {
+ $editArea.find('select').find('option').each(function() {
+ var $option = $(this);
+ $option.attr('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').attr('value', '');
+ }
+ } else {
+ $editArea.find('textarea').val('');
+ }
+ $(g.cEdit).find('input[type=text]').val('');
+ })
+ }
+
+ if($td.is('.relation')) {
+ /** @lends jQuery */
+ //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
+ */
+ var post_params = {
+ 'ajax_request' : true,
+ 'get_relational_values' : true,
+ 'server' : g.server,
+ 'db' : g.db,
+ 'table' : g.table,
+ 'column' : field_name,
+ 'token' : g.token,
+ 'curr_value' : relation_curr_value,
+ 'relation_key_or_display_column' : relation_key_or_display_column
+ }
+
+ g.lastXHR = $.post('sql.php', post_params, function(data) {
+ g.lastXHR = null;
+ $editArea.removeClass('edit_area_loading');
+ // 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('input[type=text]').val(value);
+
+ $editArea.append(data.dropdown);
+ $editArea.append('
');
+ g.isEditCellTextEditable = true;
+ }
+
+ $editArea.show();
+ }
+ },
+
+ /**
+ * Post the content of edited cell.
+ */
+ postEditedCell: function() {
+ if (g.isSaving) {
+ return;
+ }
+ g.isSaving = true;
+
+ /**
+ * @var relation_fields Array containing the name/value pairs of relational fields
+ */
+ var relation_fields = {};
+ /**
+ * @var relational_display string 'K' if relational key, 'D' if relational display column
+ */
+ var relational_display = $("#relational_display_K").attr('checked') ? 'K' : 'D';
+ /**
+ * @var transform_fields Array containing the name/value pairs for transformed fields
+ */
+ var transform_fields = {};
+ /**
+ * @var transformation_fields Boolean, if there are any transformed fields in the edited cells
+ */
+ var transformation_fields = false;
+ /**
+ * @var full_sql_query String containing the complete SQL query to update this table
+ */
+ var full_sql_query = '';
+ /**
+ * @var rel_fields_list String, url encoded representation of {@link relations_fields}
+ */
+ var rel_fields_list = '';
+ /**
+ * @var transform_fields_list String, url encoded representation of {@link transform_fields}
+ */
+ var transform_fields_list = '';
+ /**
+ * @var where_clause Array containing where clause for updated fields
+ */
+ var full_where_clause = Array();
+ /**
+ * @var is_unique Boolean, whether the rows in this table is unique or not
+ */
+ var is_unique = $('.edit_row_anchor').is('.nonunique') ? 0 : 1;
+ /**
+ * multi edit variables
+ */
+ var me_fields_name = Array();
+ var me_fields = Array();
+ var me_fields_null = Array();
+
+ // alert user if edited table is not unique
+ if (!is_unique) {
+ alert(g.alertNonUnique);
+ }
+
+ // loop each edited row
+ $('.to_be_saved').parents('tr').each(function() {
+ var $tr = $(this);
+ var where_clause = $tr.find('.where_clause').val();
+ full_where_clause.push(PMA_urldecode(where_clause));
+ var condition_array = jQuery.parseJSON($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 fields_name = Array();
+ var fields = Array();
+ var fields_null = Array();
+
+ // 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 $this_field = $(this);
+
+ /**
+ * @var field_name String containing the name of this field.
+ * @see getFieldName()
+ */
+ var field_name = getFieldName($this_field);
+
+ /**
+ * @var this_field_params Array temporary storage for the name/value of current field
+ */
+ var this_field_params = {};
+
+ if($this_field.is('.transformed')) {
+ transformation_fields = true;
+ }
+ this_field_params[field_name] = $this_field.data('value');
+
+ /**
+ * @var is_null String capturing whether 'checkbox_null__' is checked.
+ */
+ var is_null = this_field_params[field_name] === null;
+
+ fields_name.push(field_name);
+
+ if (is_null) {
+ fields_null.push('on');
+ fields.push('');
+ } else {
+ fields_null.push('');
+ fields.push($this_field.data('value'));
+
+ var cell_index = $this_field.index('.to_be_saved');
+ if($this_field.is(":not(.relation, .enum, .set, .bit)")) {
+ if($this_field.is('.transformed')) {
+ transform_fields[cell_index] = {};
+ $.extend(transform_fields[cell_index], this_field_params);
+ }
+ } else if($this_field.is('.relation')) {
+ relation_fields[cell_index] = {};
+ $.extend(relation_fields[cell_index], this_field_params);
+ }
+ }
+ // check if edited field appears in WHERE clause
+ if (where_clause.indexOf(PMA_urlencode(field_name)) > -1) {
+ var field_str = '`' + g.table + '`.' + '`' + field_name + '`';
+ for (var field in condition_array) {
+ if (field.indexOf(field_str) > -1) {
+ condition_array[field] = is_null ? 'IS NULL' : "= '" + this_field_params[field_name].replace(/'/g,"''") + "'";
+ break;
+ }
+ }
+ }
+
+ }); // end of loop for every edited cells in a row
+
+ // save new_clause
+ var new_clause = '';
+ for (var field in condition_array) {
+ new_clause += field + ' ' + condition_array[field] + ' AND ';
+ }
+ new_clause = new_clause.substring(0, new_clause.length - 5); // remove the last AND
+ new_clause = PMA_urlencode(new_clause);
+ $tr.data('new_clause', new_clause);
+ // save condition_array
+ $tr.find('.condition_array').val(JSON.stringify(condition_array));
+
+ me_fields_name.push(fields_name);
+ me_fields.push(fields);
+ me_fields_null.push(fields_null);
+
+ }); // end of loop for every edited rows
+
+ rel_fields_list = $.param(relation_fields);
+ transform_fields_list = $.param(transform_fields);
+
+ // Make the Ajax post after setting all parameters
+ /**
+ * @var post_params Object containing parameters for the POST request
+ */
+ var post_params = {'ajax_request' : true,
+ 'sql_query' : full_sql_query,
+ 'token' : g.token,
+ 'server' : g.server,
+ 'db' : g.db,
+ 'table' : g.table,
+ 'clause_is_unique' : is_unique,
+ 'where_clause' : full_where_clause,
+ 'fields[multi_edit]' : me_fields,
+ 'fields_name[multi_edit]' : me_fields_name,
+ 'fields_null[multi_edit]' : me_fields_null,
+ 'rel_fields_list' : rel_fields_list,
+ 'do_transformations' : transformation_fields,
+ 'transform_fields_list' : transform_fields_list,
+ 'relational_display' : relational_display,
+ 'goto' : 'sql.php',
+ 'submit_type' : 'save'
+ };
+
+ if (!g.saveCellsAtOnce) {
+ $(g.cEdit).find('*').attr('disabled', 'disabled');
+ var $editArea = $(g.cEdit).find('.edit_area');
+ $editArea.addClass('edit_area_posting');
+ } else {
+ $('.save_edited').addClass('saving_edited_data')
+ .find('input').attr('disabled', 'disabled'); // disable the save button
+ }
+
+ $.ajax({
+ type: 'POST',
+ url: 'tbl_replace.php',
+ data: post_params,
+ success:
+ function(data) {
+ g.isSaving = false;
+ if (!g.saveCellsAtOnce) {
+ $(g.cEdit).find('*').removeAttr('disabled');
+ $editArea.removeClass('edit_area_posting');
+ } else {
+ $('.save_edited').removeClass('saving_edited_data')
+ .find('input').removeAttr('disabled'); // enable the save button back
+ }
+ if(data.success == true) {
+ PMA_ajaxShowMessage(data.message);
+ $('.to_be_saved').each(function() {
+ var new_clause = $(this).parent('tr').data('new_clause');
+ if (new_clause != '') {
+ var $where_clause = $(this).parent('tr').find('.where_clause');
+ var old_clause = $where_clause.attr('value');
+ var decoded_old_clause = PMA_urldecode(old_clause);
+ var decoded_new_clause = PMA_urldecode(new_clause);
+
+ $where_clause.attr('value', new_clause);
+ // update Edit, Copy, and Delete links also
+ $(this).parent('tr').find('a').each(function() {
+ $(this).attr('href', $(this).attr('href').replace(old_clause, new_clause));
+ // update delete confirmation in Delete link
+ if ($(this).attr('href').indexOf('DELETE') > -1) {
+ $(this).removeAttr('onclick')
+ .unbind('click')
+ .bind('click', function() {
+ return confirmLink(this, 'DELETE FROM `' + g.db + '`.`' + g.table + '` WHERE ' +
+ decoded_new_clause + (is_unique ? '' : ' LIMIT 1'));
+ });
+ }
+ });
+ // update the multi edit checkboxes
+ $(this).parent('tr').find('input[type=checkbox]').each(function() {
+ var $checkbox = $(this);
+ var checkbox_name = $checkbox.attr('name');
+ var checkbox_value = $checkbox.attr('value');
+
+ $checkbox.attr('name', checkbox_name.replace(old_clause, new_clause));
+ $checkbox.attr('value', checkbox_value.replace(decoded_old_clause, decoded_new_clause));
+ });
+ }
+ });
+ // remove possible previous feedback message
+ $('#result_query').remove();
+ if (typeof data.sql_query != 'undefined') {
+ // display feedback
+ $('#sqlqueryresults').prepend(data.sql_query);
+ }
+ g.hideEditCell(true, data);
+
+ // remove the "Save edited cells" button
+ $('.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);
+ }
+ }
+ }) // 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($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');
+ var value;
+
+ if ($(g.cEdit).find('.edit_area').is('.edit_area_loading')) {
+ 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(":not(.relation, .enum, .set, .bit)")) {
+ this_field_params[field_name] = $(g.cEdit).find('textarea').val();
+ } else if ($this_field.is('.bit')) {
+ this_field_params[field_name] = '0b' + $(g.cEdit).find('textarea').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 {
+ // results from a drop-down
+ $test_element = $(g.cEdit).find('select');
+ if ($test_element.length != 0) {
+ this_field_params[field_name] = $test_element.val();
+ }
+
+ // results from Browse foreign value
+ $test_element = $(g.cEdit).find('span.curr_value');
+ if ($test_element.length != 0) {
+ this_field_params[field_name] = $test_element.text();
+ }
+ }
+ 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) {
+ $('.save_edited').show();
+ }
+ g.isCellEdited = true;
+ }
+
+ return need_to_post;
+ },
+
+ // save or post edited cell, depending on the configuration
+ saveOrPostEditedCell: function() {
+ var saved = g.saveEditedCell();
+ if (!g.saveCellsAtOnce) {
+ if (saved) {
+ g.postEditedCell();
+ } else {
+ g.hideEditCell(true);
+ }
+ } else {
+ if (saved) {
+ g.hideEditCell(true, true);
+ } else {
+ g.hideEditCell(true);
+ }
+ }
+ },
+
+ // initialize grid editing feature
+ initGridEdit: function() {
+ $(t).find('td.data')
+ .click(function(e) {
+ if (g.isCellEditActive) {
+ g.saveOrPostEditedCell();
+ e.stopPropagation();
+ } else {
+ g.showEditCell(this);
+ e.stopPropagation();
+ }
+ // prevent default action when clicking on "link" in a table
+ if ($(e.target).is('a')) {
+ e.preventDefault();
+ }
+ });
+ $(g.cEdit).find('input[type=text]').focus(function(e) {
+ g.showEditArea();
+ });
+ $(g.cEdit).find('input[type=text], select').live('keydown', function(e) {
+ if (e.which == 13) {
+ // post on pressing "Enter"
+ e.preventDefault();
+ g.saveOrPostEditedCell();
+ }
+ });
+ $(g.cEdit).keydown(function(e) {
+ if (!g.isEditCellTextEditable) {
+ // prevent text editing
+ e.preventDefault();
+ }
+ });
+ $('html').click(function(e) {
+ // hide edit cell if the click is not from g.cEdit
+ if ($(e.target).parents().index(g.cEdit) == -1) {
+ g.hideEditCell();
+ }
+ });
+ $('html').keydown(function(e) {
+ if (e.which == 27 && g.isCellEditActive) {
+
+ // cancel on pressing "Esc"
+ g.hideEditCell(true);
+ }
+ });
+ $('.save_edited').click(function() {
+ g.hideEditCell();
+ g.postEditedCell();
+ });
+ $(window).bind('beforeunload', function(e) {
+ if (g.isCellEdited) {
+ return g.saveCellWarning;
+ }
+ });
}
}
@@ -451,7 +1254,8 @@
g.cPointer = document.createElement('div'); // column pointer, used when reordering column
g.cDrop = document.createElement('div'); // column drop-down arrows
g.cList = document.createElement('div'); // column visibility list
-
+ g.cEdit = document.createElement('div'); // cell edit
+
// adjust g.cCpy
g.cCpy.className = 'cCpy';
$(g.cCpy).hide();
@@ -466,7 +1270,12 @@
// adjust g.cList
g.cList.className = 'cList';
$(g.cList).hide();
-
+
+ // adjust g.cEdit
+ g.cEdit.className = 'cEdit';
+ $(g.cEdit).html('');
+ $(g.cEdit).hide();
+
// chain table and grid together
t.grid = g;
g.t = t;
@@ -491,10 +1300,25 @@
// assign column reorder & column sort hint
g.reorderHint = PMA_messages['strColOrderHint'];
g.sortHint = PMA_messages['strSortHint'];
- g.markHint = PMA_messages['strMarkHint'];
- g.colVisibHint = PMA_messages['strVisibHint'];
- g.showAllColText = PMA_messages['strShowAll'];
-
+ g.markHint = PMA_messages['strColMarkHint'];
+ g.colVisibHint = PMA_messages['strColVisibHint'];
+ g.showAllColText = PMA_messages['strShowAllCol'];
+
+ // assign cell editing hint
+ g.cellEditHint = PMA_messages['strCellEditHint'];
+ g.saveCellWarning = PMA_messages['strSaveCellWarning'];
+ g.alertNonUnique = PMA_messages['strAlertNonUnique'];
+
+ // initialize cell editing configuration
+ g.saveCellsAtOnce = $('#save_cells_at_once').val();
+
+ // assign common hidden inputs
+ var $common_hidden_inputs = $('.common_hidden_inputs');
+ g.token = $common_hidden_inputs.find('input[name=token]').val();
+ 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();
+
// initialize column order
$col_order = $('#col_order');
if ($col_order.length > 0) {
@@ -663,7 +1487,11 @@
$(t).find('td, th.draggable').mouseenter(function() {
g.hideColList();
});
-
+ // edit cell event
+ if ($(t).is('.ajax')) {
+ g.initGridEdit();
+ }
+
// add table class
$(t).addClass('pma_table');
@@ -675,6 +1503,7 @@
$(g.gDiv).append(g.cDrop);
$(g.gDiv).append(g.cList);
$(g.gDiv).append(g.cCpy);
+ $(g.gDiv).append(g.cEdit);
// some adjustment
g.refreshRestoreButton();
diff --git a/js/messages.php b/js/messages.php
index a63184043f..5f4e12b040 100644
--- a/js/messages.php
+++ b/js/messages.php
@@ -226,7 +226,6 @@ $js_messages['strImportCSV'] = __('Note: If the file contains multiple tables, t
/* For sql.js */
$js_messages['strHideQueryBox'] = __('Hide query box');
$js_messages['strShowQueryBox'] = __('Show query box');
-$js_messages['strInlineEdit'] = __('Inline Edit');
$js_messages['strEdit'] = __('Edit');
$js_messages['strSave'] = __('Save');
$js_messages['strHide'] = __('Hide');
@@ -254,6 +253,16 @@ $js_messages['strLeavingDesigner'] = __('You haven\'t saved the changes in the l
/* Visual query builder (js/pmd/move.js) */
$js_messages['strAddOption'] = __('Add an option for column ');
+/* For makegrid.js (column reordering, show/hide column, grid editing) */
+$js_messages['strCellEditHint'] = __('Press escape to cancel editing');
+$js_messages['strSaveCellWarning'] = __('You have edited some data and they have not been saved. Are you sure you want to leave this page before saving the data?');
+$js_messages['strColOrderHint'] = __('Drag to reorder');
+$js_messages['strSortHint'] = __('Click to sort');
+$js_messages['strColMarkHint'] = __('Click to mark/unmark');
+$js_messages['strColVisibHint'] = __('Click the drop-down arrow to toggle column\'s visibility');
+$js_messages['strShowAllCol'] = __('Show all');
+$js_messages['strAlertNonUnique'] = __('This table contains no unique field. Features related to the grid edit, checkbox, Edit, Copy and Delete links may not work after saving.');
+
/* password generation */
$js_messages['strGeneratePassword'] = __('Generate password');
$js_messages['strGenerate'] = __('Generate');
@@ -268,12 +277,6 @@ $js_messages['strNewerVersion'] = __('A newer version of phpMyAdmin is available
$js_messages['strLatestAvailable'] = __(', latest stable version:');
$js_messages['strUpToDate'] = __('up to date');
-/* Browsing grid */
-$js_messages['strColOrderHint'] = __('Drag to reorder');
-$js_messages['strSortHint'] = __('Click to sort');
-$js_messages['strMarkHint'] = __('Click to mark/unmark');
-$js_messages['strVisibHint'] = __('Click the drop-down arrow to toggle column\'s visibility');
-$js_messages['strShowAll'] = __('Show all');
echo "var PMA_messages = new Array();\n";
foreach ($js_messages as $name => $js_message) {
diff --git a/js/navigation.js b/js/navigation.js
index c70d428c18..e4d7a207b1 100644
--- a/js/navigation.js
+++ b/js/navigation.js
@@ -205,9 +205,9 @@ $(document).ready(function(){
/* Jump to recent table */
$('#recentTable').change(function() {
if (this.value != '') {
- var arr = this.value.split('.');
- window.parent.setDb(arr[0]);
- window.parent.setTable(arr[1]);
+ var arr = jQuery.parseJSON(this.value);
+ window.parent.setDb(arr['db']);
+ window.parent.setTable(arr['table']);
window.parent.refreshMain($('#LeftDefaultTabTable')[0].value);
}
});
diff --git a/js/sql.js b/js/sql.js
index 2b77af12f0..4386dcec6f 100644
--- a/js/sql.js
+++ b/js/sql.js
@@ -22,12 +22,12 @@ function PMA_urldecode(str)
function PMA_urlencode(str)
{
- return encodeURIComponent(str.replace(/\%20/g, '+'));
+ return encodeURIComponent(str).replace(/\%20/g, '+');
}
/**
* Get the field name for the current field. Required to construct the query
- * for inline editing
+ * for grid editing
*
* @param $this_field jQuery object that points to the current field's tr
*/
@@ -37,12 +37,13 @@ function getFieldName($this_field)
var this_field_index = $this_field.index();
// ltr or rtl direction does not impact how the DOM was generated
// check if the action column in the left exist
- var leftActionExist = !$('#table_results').find('th:first').hasClass('draggable');
- // 5 columns to account for the checkbox, edit, appended inline edit, copy and delete anchors but index is zero-based so substract 4
- var field_name = $('#table_results').find('thead').find('th:nth('+ (this_field_index - (leftActionExist ? 4 : 0)) + ') a').text();
+ var left_action_exist = !$('#table_results').find('th:first').hasClass('draggable');
+ // number of column span for checkbox and Actions
+ var left_action_skip = left_action_exist ? $('#table_results').find('th:first').attr('colspan') - 1 : 0;
+ var field_name = $('#table_results').find('thead').find('th:eq('+ (this_field_index - left_action_skip) + ') a').text();
// happens when just one row (headings contain no a)
if ("" == field_name) {
- field_name = $('#table_results').find('thead').find('th:nth('+ (this_field_index - (leftActionExist ? 4 : 0)) + ')').text();
+ field_name = $('#table_results').find('thead').find('th:eq('+ (this_field_index - left_action_skip) + ')').text();
}
field_name = $.trim(field_name);
@@ -50,69 +51,6 @@ function getFieldName($this_field)
return field_name;
}
-/**
- * The function that iterates over each row in the table_results and appends a
- * new inline edit anchor to each table row.
- *
- */
-function appendInlineAnchor()
-{
- // TODO: remove two lines below if vertical display mode has been completely removed
- var disp_mode = $("#top_direction_dropdown").val();
-
- if (disp_mode != 'vertical') {
- $('.edit_row_anchor').each(function() {
-
- var $this_td = $(this);
- $this_td.removeClass('edit_row_anchor');
-
- var $cloned_anchor = $this_td.clone();
-
- var $img_object = $cloned_anchor.find('img').attr('title', PMA_messages['strInlineEdit']);
- if ($img_object.length != 0) {
- $img_object.removeClass('ic_b_edit');
- $img_object.addClass('ic_b_inline_edit');
-
- $cloned_anchor.find('a').attr('href', '#');
- var $edit_span = $cloned_anchor.find('span:contains("' + PMA_messages['strEdit'] + '")');
- var $span = $cloned_anchor.find('a').find('span');
- if ($edit_span.length > 0) {
- $span.text(' ' + PMA_messages['strInlineEdit']);
- $span.prepend($img_object);
- } else {
- $span.text('');
- $span.append($img_object);
- }
- } else {
- // Only text is displayed. See $cfg['PropertiesIconic']
- $cloned_anchor.find('a').attr('href', '#');
- $cloned_anchor.find('a span').text(PMA_messages['strInlineEdit']);
-
- // the link was too big so is there
- $img_object = $cloned_anchor.find('input:image').attr('title', PMA_messages['strInlineEdit']);
- if ($img_object.length > 0) {
- $img_object.removeClass('ic_b_edit');
- $img_object.addClass('ic_b_inline_edit');
- }
- $cloned_anchor
- .find('.clickprevimage')
- .text(' ' + PMA_messages['strInlineEdit']);
- }
-
- $cloned_anchor
- .addClass('inline_edit_anchor');
-
- $this_td.after($cloned_anchor);
- });
-
- $('#resultsForm').find('thead, tbody').find('th').each(function() {
- var $this_th = $(this);
- if ($this_th.attr('colspan') == 4) {
- $this_th.attr('colspan', '5');
- }
- });
- }
-}
/**#@+
* @namespace jQuery
@@ -127,7 +65,7 @@ function appendInlineAnchor()
*
Paginate the results table
*
Sort the results table
*
Change table according to display options
- *
Inline editing of data
+ *
Grid editing of data
*
*
* @name document.ready
@@ -150,15 +88,6 @@ $(document).ready(function() {
.toggle($(this).attr('value').length > 0);
}).trigger('keyup');
- /**
- * Attach the {@link appendInlineAnchor} function to a custom event, which
- * will be triggered manually everytime the table of results is reloaded
- * @memberOf jQuery
- */
- $("#sqlqueryresults").live('appendAnchor',function() {
- appendInlineAnchor();
- })
-
/**
* Attach the {@link makegrid} function to a custom event, which will be
* triggered manually everytime the table of results is reloaded
@@ -170,21 +99,13 @@ $(document).ready(function() {
/**
* Attach the {@link refreshgrid} function to a custom event, which will be
- * triggered manually everytime the table of results is manipulated (e.g., by inline edit)
+ * triggered manually everytime the table of results is manipulated
* @memberOf jQuery
*/
$("#sqlqueryresults").live('refreshgrid', function() {
$('#table_results').refreshgrid();
})
- /**
- * Trigger the appendAnchor event to prepare the first table for inline edit
- * (see $GLOBALS['cfg']['AjaxEnable'])
- * @memberOf jQuery
- * @name sqlqueryresults_trigger
- */
- $("#sqlqueryresults.ajax").trigger('appendAnchor');
-
/**
* Append the "Show/Hide query box" message to the query input form
*
@@ -290,7 +211,6 @@ $(document).ready(function() {
$sqlqueryresults
.show()
.html(data)
- .trigger('appendAnchor')
.trigger('makegrid');
$('#togglequerybox').show();
if ($("#togglequerybox").siblings(":visible").length > 0) {
@@ -332,7 +252,6 @@ $(document).ready(function() {
$.post($form.attr('action'), $form.serialize(), function(data) {
$("#sqlqueryresults")
.html(data)
- .trigger('appendAnchor')
.trigger('makegrid');
PMA_init_slider();
@@ -357,7 +276,6 @@ $(document).ready(function() {
$.post($form.attr('action'), $form.serialize() + '&ajax_request=true', function(data) {
$("#sqlqueryresults")
.html(data)
- .trigger('appendAnchor')
.trigger('makegrid');
PMA_init_slider();
PMA_ajaxRemoveMessage($msgbox);
@@ -384,7 +302,6 @@ $(document).ready(function() {
$.get($anchor.attr('href'), $anchor.serialize() + '&ajax_request=true', function(data) {
$("#sqlqueryresults")
.html(data)
- .trigger('appendAnchor')
.trigger('makegrid');
PMA_ajaxRemoveMessage($msgbox);
}) // end $.get()
@@ -404,535 +321,12 @@ $(document).ready(function() {
$.post($form.attr('action'), $form.serialize() + '&ajax_request=true' , function(data) {
$("#sqlqueryresults")
.html(data)
- .trigger('appendAnchor')
.trigger('makegrid');
PMA_init_slider();
}) // end $.post()
})
//end displayOptionsForm handler
- /**
- * Ajax Event handlers for Inline Editing
- */
-
- /**
- * On click, replace the fields of current row with an input/textarea
- * @memberOf jQuery
- * @name inline_edit_start
- * @see PMA_ajaxShowMessage()
- * @see getFieldName()
- */
- $(".inline_edit_anchor span a").live('click', function(event) {
- /** @lends jQuery */
- event.preventDefault();
-
- var $edit_td = $(this).parents('td');
- $edit_td.removeClass('inline_edit_anchor').addClass('inline_edit_active').parent('tr').addClass('noclick');
-
- // Adding submit and hide buttons to inline edit
.
- // For "hide" button the original data to be restored is
- // kept in the jQuery data element 'original_data' inside the
.
- // Looping through all columns or rows, to find the required data and then storing it in an array.
-
- var $this_children = $edit_td.children('span.nowrap').children('a').children('span.nowrap');
- // Keep the original data preserved.
- $data_a = $edit_td.children('span.nowrap').children('a').clone();
-
- // Change the inline edit to save.
- var $img_object = $this_children.find('img');
-
- // If texts are displayed. See $cfg['PropertiesIconic']
- if ($this_children.parent('a').find('span:contains("' + PMA_messages['strInlineEdit'] + '")').length > 0) {
- $this_children.text(' ' + PMA_messages['strSave']);
- } else {
- $this_children.empty();
- }
-
- // If icons are displayed. See $cfg['PropertiesIconic']
- if ($img_object.length > 0) {
- $img_object.attr('title', PMA_messages['strSave']);
- $img_object.removeClass('ic_b_inline_edit');
- $img_object.addClass('ic_b_save');
- $this_children.prepend($img_object);
- }
-
- // Clone the save link and change it to create the hide link.
- var $hide_a = $edit_td.children('span.nowrap').children('a').clone().attr('id', 'hide');
- var $hide_span = $hide_a.find('span');
- var $img_object = $hide_a.find('span img');
-
- // If texts are displayed. See $cfg['PropertiesIconic']
- if ($hide_a.find('span:contains("' + PMA_messages['strSave'] + '")').length > 0) {
- $hide_span.text(' ' + PMA_messages['strHide']);
- } else {
- $hide_span.empty();
- }
-
- // If icons are displayed. See $cfg['PropertiesIconic']
- if ($img_object.length > 0) {
- $img_object.attr('title', PMA_messages['strHide']);
- $img_object.removeClass('ic_b_save');
- $img_object.addClass('ic_b_close');
- $hide_span.prepend($img_object);
- }
-
- // Add hide icon and/or text.
- $edit_td.children('span.nowrap').append($('
')).append($hide_a);
-
- $('#table_results tbody tr td span a#hide').click(function() {
- var $this_hide = $(this).parents('td');
-
- var $this_span = $this_hide.find('span');
- $this_span.find('a, br').remove();
- $this_span.append($data_a.clone());
-
- $this_hide.removeClass("inline_edit_active hover").addClass("inline_edit_anchor");
- $this_hide.parent().removeClass("hover noclick");
- $this_hide.siblings().removeClass("hover");
-
- var $input_siblings = $this_hide.parent('tr').find('.inline_edit');
- var txt = '';
- $input_siblings.each(function() {
- var $this_hide_siblings = $(this);
- txt = $this_hide_siblings.data('original_data');
- if($this_hide_siblings.children('span').children().length != 0) {
- $this_hide_siblings.children('span').empty();
- $this_hide_siblings.children('span').append(txt);
- }
- });
- $(this).prev().prev().remove();
- $(this).prev().remove();
- $(this).remove();
-
- // refresh the grid
- $("#sqlqueryresults").trigger('refreshgrid');
- });
-
- // Initialize some variables
- var this_row_index = $edit_td.parent().index();
- var $input_siblings = $edit_td.parent('tr').find('.inline_edit');
- var where_clause = $edit_td.parent('tr').find('.where_clause').val();
-
- $input_siblings.each(function() {
- /** @lends jQuery */
- /**
- * @var data_value Current value of this field
- */
- var data_value = $(this).children('span').html();
-
- // We need to retrieve the value from the server for truncated/relation fields
- // Find the field name
-
- /**
- * @var this_field Object referring to this field (
)
- */
- var $this_field = $(this);
- /**
- * @var this_field_span Object referring to this field's child ()
- */
- var $this_field_span = $(this).children('span');
- /**
- * @var field_name String containing the name of this field.
- * @see getFieldName()
- */
- var field_name = getFieldName($this_field);
- /**
- * @var relation_curr_value String current value of the field (for fields that are foreign keyed).
- */
- var relation_curr_value = $this_field.find('a').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 relation_key_or_display_column = $this_field.find('a').attr('title');
- /**
- * @var curr_value String current value of the field (for fields that are of type enum or set).
- */
- var curr_value = $this_field_span.text();
-
- if($this_field.is(':not(.not_null)')){
- // add a checkbox to mark null for all the field that are nullable.
- $this_field_span.html('
Null :
');
- // check the 'checkbox_null__' if the corresponding value is null
- if($this_field.is('.null')) {
- $('.checkbox_null_' + field_name + '_' + this_row_index).attr('checked', true);
- }
-
- // if the select/editor is changed un-check the 'checkbox_null__'.
- if ($this_field.is('.enum, .set')) {
- $this_field.find('select').live('change', function(e) {
- $('.checkbox_null_' + field_name + '_' + this_row_index).attr('checked', false);
- })
- } else if ($this_field.is('.relation')) {
- $this_field.find('select').live('change', function(e) {
- $('.checkbox_null_' + field_name + '_' + this_row_index).attr('checked', false);
- })
- $this_field.find('.browse_foreign').live('click', function(e) {
- $('.checkbox_null_' + field_name + '_' + this_row_index).attr('checked', false);
- })
- } else {
- $this_field.find('textarea').live('keypress', function(e) {
- // FF errorneously triggers for modifier keys such as tab (bug #3357837)
- if (e.which != 0) {
- $('.checkbox_null_' + field_name + '_' + this_row_index).attr('checked', false);
- }
- })
- }
-
- // if 'checkbox_null__' is clicked empty the corresponding select/editor.
- $('.checkbox_null_' + field_name + '_' + this_row_index).bind('click', function(e) {
- if ($this_field.is('.enum')) {
- $this_field.find('select').attr('value', '');
- } else if ($this_field.is('.set')) {
- $this_field.find('select').find('option').each(function() {
- var $option = $(this);
- $option.attr('selected', false);
- })
- } else if ($this_field.is('.relation')) {
- // if the dropdown is there to select the foreign value
- if ($this_field.find('select').length > 0) {
- $this_field.find('select').attr('value', '');
- // if foriegn value is selected by browsing foreing values
- } else {
- $this_field.find('span.curr_value').empty();
- }
- } else {
- $this_field.find('textarea').val('');
- }
- })
-
- } else {
- $this_field_span.html('');
- }
-
- // In each input sibling, wrap the current value in a textarea
- // and store the current value in a hidden span
- if($this_field.is(':not(.truncated, .transformed, .relation, .enum, .set, .null)')) {
- // handle non-truncated, non-transformed, non-relation values
-
- value = data_value.replace(" ", "\n");
- // We don't need to get any more data, just wrap the value
- $this_field_span.append('');
- $this_field.data('original_data', data_value);
- }
- else if($this_field.is('.truncated, .transformed')) {
- /** @lends jQuery */
- //handle truncated/transformed values values
-
- /**
- * @var sql_query String containing the SQL query used to retrieve value of truncated/transformed data
- */
- var sql_query = 'SELECT `' + field_name + '` FROM `' + window.parent.table + '` WHERE ' + PMA_urldecode(where_clause);
-
- // Make the Ajax call and get the data, wrap it and insert it
- $.post('sql.php', {
- 'token' : window.parent.token,
- 'db' : window.parent.db,
- 'ajax_request' : true,
- 'sql_query' : sql_query,
- 'inline_edit' : true
- }, function(data) {
- if(data.success == true) {
- $this_field_span.append('');
- $this_field.data('original_data', data_value);
- $("#sqlqueryresults").trigger('refreshgrid');
- }
- else {
- PMA_ajaxShowMessage(data.error);
- }
- }) // end $.post()
- }
- else if($this_field.is('.relation')) {
- /** @lends jQuery */
- //handle relations
-
- /**
- * @var post_params Object containing parameters for the POST request
- */
- var post_params = {
- 'ajax_request' : true,
- 'get_relational_values' : true,
- 'db' : window.parent.db,
- 'table' : window.parent.table,
- 'column' : field_name,
- 'token' : window.parent.token,
- 'curr_value' : relation_curr_value,
- 'relation_key_or_display_column' : relation_key_or_display_column
- }
-
- $.post('sql.php', post_params, function(data) {
- $this_field_span.append(data.dropdown);
- $this_field.data('original_data', data_value);
- $("#sqlqueryresults").trigger('refreshgrid');
- }) // end $.post()
- }
- else if($this_field.is('.enum')) {
- /** @lends jQuery */
- //handle enum fields
-
- /**
- * @var post_params Object containing parameters for the POST request
- */
- var post_params = {
- 'ajax_request' : true,
- 'get_enum_values' : true,
- 'db' : window.parent.db,
- 'table' : window.parent.table,
- 'column' : field_name,
- 'token' : window.parent.token,
- 'curr_value' : curr_value
- }
- $.post('sql.php', post_params, function(data) {
- $this_field_span.append(data.dropdown);
- $this_field.data('original_data', data_value);
- $("#sqlqueryresults").trigger('refreshgrid');
- }) // end $.post()
- }
- else if($this_field.is('.set')) {
- /** @lends jQuery */
- //handle set fields
-
- /**
- * @var post_params Object containing parameters for the POST request
- */
- var post_params = {
- 'ajax_request' : true,
- 'get_set_values' : true,
- 'db' : window.parent.db,
- 'table' : window.parent.table,
- 'column' : field_name,
- 'token' : window.parent.token,
- 'curr_value' : curr_value
- }
-
- $.post('sql.php', post_params, function(data) {
- $this_field_span.append(data.select);
- $this_field.data('original_data', data_value);
- $("#sqlqueryresults").trigger('refreshgrid');
- }) // end $.post()
- }
- else if($this_field.is('.null')) {
- //handle null fields
- $this_field_span.append('');
- $this_field.data('original_data', 'NULL');
- }
- });
-
- // refresh the grid
- $("#sqlqueryresults").trigger('refreshgrid');
-
- }) // End On click, replace the current field with an input/textarea
-
- /**
- * After editing, clicking again should post data
- *
- * @memberOf jQuery
- * @name inline_edit_save
- * @see PMA_ajaxShowMessage()
- * @see getFieldName()
- */
- $(".inline_edit_active span a").live('click', function(event) {
- /** @lends jQuery */
-
- event.preventDefault();
-
- /**
- * @var $this_td Object referring to the td containing the
- * "Inline Edit" link that was clicked to save the row that is
- * being edited
- *
- */
- var $this_td = $(this).parents('td');
- var $test_element = ''; // to test the presence of a element
-
- // Initialize variables
- var $input_siblings = $this_td.parent('tr').find('.inline_edit');
- var where_clause = $this_td.parent('tr').find('.where_clause').val();
-
- /**
- * @var nonunique Boolean, whether this row is unique or not
- */
- if($this_td.is('.nonunique')) {
- var nonunique = 0;
- }
- else {
- var nonunique = 1;
- }
-
- // Collect values of all fields to submit, we don't know which changed
- /**
- * @var relation_fields Array containing the name/value pairs of relational fields
- */
- var relation_fields = {};
- /**
- * @var relational_display string 'K' if relational key, 'D' if relational display column
- */
- var relational_display = $("#relational_display_K").attr('checked') ? 'K' : 'D';
- /**
- * @var transform_fields Array containing the name/value pairs for transformed fields
- */
- var transform_fields = {};
- /**
- * @var transformation_fields Boolean, if there are any transformed fields in this row
- */
- var transformation_fields = false;
-
- /**
- * @var sql_query String containing the SQL query to update this row
- */
- var sql_query = 'UPDATE `' + window.parent.table + '` SET ';
-
- var need_to_post = false;
-
- var new_clause = '';
- var prev_index = -1;
-
- $input_siblings.each(function() {
- /** @lends jQuery */
- /**
- * @var this_field Object referring to this field (
)
- */
- var $this_field = $(this);
-
- /**
- * @var field_name String containing the name of this field.
- * @see getFieldName()
- */
- var field_name = getFieldName($this_field);
-
- /**
- * @var this_field_params Array temporary storage for the name/value of current field
- */
- var this_field_params = {};
-
- if($this_field.is('.transformed')) {
- transformation_fields = true;
- }
- /**
- * @var is_null String capturing whether 'checkbox_null__' is checked.
- */
- var is_null = $this_field.find('input:checkbox').is(':checked');
- var value;
- var addQuotes = true;
-
- if (is_null) {
- sql_query += ' `' + field_name + "`=NULL , ";
- need_to_post = true;
- } else {
- if($this_field.is(":not(.relation, .enum, .set, .bit)")) {
- this_field_params[field_name] = $this_field.find('textarea').val();
- if($this_field.is('.transformed')) {
- $.extend(transform_fields, this_field_params);
- }
- } else if ($this_field.is('.bit')) {
- this_field_params[field_name] = '0b' + $this_field.find('textarea').val();
- addQuotes = false;
- } else if ($this_field.is('.set')) {
- $test_element = $this_field.find('select');
- this_field_params[field_name] = $test_element.map(function(){
- return $(this).val();
- }).get().join(",");
- } else {
- // results from a drop-down
- $test_element = $this_field.find('select');
- if ($test_element.length != 0) {
- this_field_params[field_name] = $test_element.val();
- }
-
- // results from Browse foreign value
- $test_element = $this_field.find('span.curr_value');
- if ($test_element.length != 0) {
- this_field_params[field_name] = $test_element.text();
- }
-
- if($this_field.is('.relation')) {
- $.extend(relation_fields, this_field_params);
- }
- }
- if(where_clause.indexOf(field_name) > prev_index){
- new_clause += '`' + window.parent.table + '`.' + '`' + field_name + "` = '" + this_field_params[field_name].replace(/'/g,"''") + "'" + ' AND ';
- }
- if (this_field_params[field_name] != $this_field.data('original_data')) {
- if (addQuotes == true) {
- sql_query += ' `' + field_name + "`='" + this_field_params[field_name].replace(/'/g, "''") + "', ";
- } else {
- sql_query += ' `' + field_name + "`=" + this_field_params[field_name].replace(/'/g, "''") + ", ";
- }
- need_to_post = true;
- }
- }
- })
-
- /*
- * update the where_clause, remove the last appended ' AND '
- * */
-
- //Remove the last ',' appended in the above loop
- sql_query = sql_query.replace(/,\s$/, '');
- //Fix non-escaped backslashes
- sql_query = sql_query.replace(/\\/g, '\\\\');
- new_clause = new_clause.substring(0, new_clause.length-5);
- new_clause = PMA_urlencode(new_clause);
- sql_query += ' WHERE ' + PMA_urldecode(where_clause);
- // Avoid updating more than one row in case there is no primary key
- // (happened only for duplicate rows)
- sql_query += ' LIMIT 1';
- /**
- * @var rel_fields_list String, url encoded representation of {@link relations_fields}
- */
- var rel_fields_list = $.param(relation_fields);
-
- /**
- * @var transform_fields_list String, url encoded representation of {@link transform_fields}
- */
- var transform_fields_list = $.param(transform_fields);
-
- // if inline_edit is successful, we need to go back to default view
- var $del_hide = $(this).parent();
- var $chg_submit = $(this);
-
- if (need_to_post) {
- // Make the Ajax post after setting all parameters
- /**
- * @var post_params Object containing parameters for the POST request
- */
- var post_params = {'ajax_request' : true,
- 'sql_query' : sql_query,
- 'token' : window.parent.token,
- 'db' : window.parent.db,
- 'table' : window.parent.table,
- 'clause_is_unique' : nonunique,
- 'where_clause' : where_clause,
- 'rel_fields_list' : rel_fields_list,
- 'do_transformations' : transformation_fields,
- 'transform_fields_list' : transform_fields_list,
- 'relational_display' : relational_display,
- 'goto' : 'sql.php',
- 'submit_type' : 'save'
- };
-
- $.post('tbl_replace.php', post_params, function(data) {
- if(data.success == true) {
- PMA_ajaxShowMessage(data.message);
- $this_td.parent('tr').find('.where_clause').attr('value', new_clause);
- // remove possible previous feedback message
- $('#result_query').remove();
- if (typeof data.sql_query != 'undefined') {
- // display feedback
- $('#sqlqueryresults').prepend(data.sql_query);
- }
- PMA_unInlineEditRow($del_hide, $chg_submit, $this_td, $input_siblings, data);
- } else {
- PMA_ajaxShowMessage(data.error);
- };
- }) // end $.post()
- } else {
- // no posting was done but still need to display the row
- // in its previous format
- PMA_unInlineEditRow($del_hide, $chg_submit, $this_td, $input_siblings, '');
- }
- }) // End After editing, clicking again should post data
-
/**
* Ajax Event for table row change
* */
@@ -1088,102 +482,6 @@ $(document).ready(function() {
}, 'top.frame_content') // end $(document).ready()
-/**
- * Visually put back the row in the state it was before entering Inline edit
- *
- * (when called in the situation where no posting was done, the data
- * parameter is empty)
- */
-function PMA_unInlineEditRow($del_hide, $chg_submit, $this_td, $input_siblings, data)
-{
-
- // deleting the hide button. remove