1 /* vim: set expandtab sw=4 ts=4 sts=4: */
3 * @fileoverview functions used wherever an sql query form is used
6 * @requires js/functions.js
11 * decode a string URL_encoded
14 * @return string the URL-decoded string
17 function PMA_urldecode(str) {
18 return decodeURIComponent(str.replace(/\+/g, '%20'));
22 * Get the field name for the current field. Required to construct the query
25 * @param $this_field jQuery object that points to the current field's tr
26 * @param disp_mode string
28 function getFieldName($this_field, disp_mode) {
30 if(disp_mode == 'vertical') {
31 var field_name = $this_field.siblings('th').find('a').text();
32 // happens when just one row (headings contain no a)
33 if ("" == field_name) {
34 field_name = $this_field.siblings('th').text();
38 var this_field_index = $this_field.index();
39 // ltr or rtl direction does not impact how the DOM was generated
41 // 5 columns to account for the checkbox, edit, appended inline edit, copy and delete anchors but index is zero-based so substract 4
42 var field_name = $('#table_results').find('thead').find('th:nth('+ (this_field_index-4 )+') a').text();
43 // happens when just one row (headings contain no a)
44 if ("" == field_name) {
45 field_name = $('#table_results').find('thead').find('th:nth('+ (this_field_index-4 )+')').text();
49 field_name = $.trim(field_name);
55 * The function that iterates over each row in the table_results and appends a
56 * new inline edit anchor to each table row.
59 function appendInlineAnchor() {
60 var disp_mode = $("#top_direction_dropdown").val();
62 if (disp_mode == 'vertical') {
63 // there can be one or two tr containing this class, depending
64 // on the ModifyDeleteAtLeft and ModifyDeleteAtRight cfg parameters
65 $('#table_results tr')
66 .find('.edit_row_anchor')
67 .removeClass('.edit_row_anchor')
68 .parent().each(function() {
69 var $this_tr = $(this);
70 var $cloned_tr = $this_tr.clone();
72 var $img_object = $cloned_tr.find('img:first').attr('title', PMA_messages['strInlineEdit']);
73 if ($img_object.length != 0) {
74 var img_src = $img_object.attr('src').replace(/b_edit/,'b_inline_edit');
75 $img_object.attr('src', img_src);
79 .addClass('inline_edit_anchor')
80 .find('a').attr('href', '#')
82 .text(' ' + PMA_messages['strInlineEdit'])
83 .prepend($img_object);
85 $cloned_tr.insertAfter($this_tr);
88 $('#rowsDeleteForm').find('tbody').find('th').each(function() {
89 var $this_th = $(this);
90 if ($this_th.attr('rowspan') == 4) {
91 $this_th.attr('rowspan', '5');
97 $('.edit_row_anchor').each(function() {
99 var $this_td = $(this);
100 $this_td.removeClass('edit_row_anchor');
102 var $cloned_anchor = $this_td.clone();
104 var $img_object = $cloned_anchor.find('img').attr('title', PMA_messages['strInlineEdit']);
105 if ($img_object.length != 0) {
106 var img_src = $img_object.attr('src').replace(/b_edit/,'b_inline_edit');
107 $img_object.attr('src', img_src);
109 .find('a').attr('href', '#')
111 .text(' ' + PMA_messages['strInlineEdit']);
115 .prepend($img_object);
117 // the link was too big so <input type="image"> is there
118 $img_object = $cloned_anchor.find('input:image').attr('title', PMA_messages['strInlineEdit']);
119 var img_src = $img_object.attr('src').replace(/b_edit/,'b_inline_edit');
120 $img_object.attr('src', img_src);
122 .find('.clickprevimage')
123 .text(' ' + PMA_messages['strInlineEdit']);
127 .addClass('inline_edit_anchor');
129 $this_td.after($cloned_anchor);
132 $('#rowsDeleteForm').find('thead, tbody').find('th').each(function() {
133 var $this_th = $(this);
134 if ($this_th.attr('colspan') == 4) {
135 $this_th.attr('colspan', '5');
146 * @description <p>Ajax scripts for sql and browse pages</p>
148 * Actions ajaxified here:
150 * <li>Retrieve results of an SQL query</li>
151 * <li>Paginate the results table</li>
152 * <li>Sort the results table</li>
153 * <li>Change table according to display options</li>
154 * <li>Inline editing of data</li>
157 * @name document.ready
160 $(document).ready(function() {
163 * Set a parameter for all Ajax queries made on this page. Don't let the
164 * web server serve cached pages
171 * current value of the direction in which the table is displayed
176 var disp_mode = $("#top_direction_dropdown").val();
179 * Update value of {@link jQuery.disp_mode} everytime the direction dropdown changes value
181 * @name direction_dropdown_change
183 $("#top_direction_dropdown, #bottom_direction_dropdown").live('change', function(event) {
184 disp_mode = $(this).val();
188 * Attach the {@link appendInlineAnchor} function to a custom event, which
189 * will be triggered manually everytime the table of results is reloaded
192 $("#sqlqueryresults").live('appendAnchor',function() {
193 appendInlineAnchor();
197 * Trigger the appendAnchor event to prepare the first table for inline edit
198 * (see $GLOBALS['cfg']['AjaxEnable'])
200 * @name sqlqueryresults_trigger
202 $("#sqlqueryresults.ajax").trigger('appendAnchor');
205 * Append the "Show/Hide query box" message to the query input form
208 * @name appendToggleSpan
210 // do not add this link more than once
211 if (! $('#sqlqueryform').find('a').is('#togglequerybox')) {
212 $('<a id="togglequerybox"></a>')
213 .html(PMA_messages['strHideQueryBox'])
214 .appendTo("#sqlqueryform")
215 // initially hidden because at this point, nothing else
216 // appears under the link
219 // Attach the toggling of the query box visibility to a click
220 $("#togglequerybox").bind('click', function() {
222 $link.siblings().slideToggle("fast");
223 if ($link.text() == PMA_messages['strHideQueryBox']) {
224 $link.text(PMA_messages['strShowQueryBox']);
225 // cheap trick to add a spacer between the menu tabs
226 // and "Show query box"; feel free to improve!
227 $('#togglequerybox_spacer').remove();
228 $link.before('<br id="togglequerybox_spacer" />');
230 $link.text(PMA_messages['strHideQueryBox']);
232 // avoid default click action
238 * Ajax Event handler for 'SQL Query Submit'
240 * @see PMA_ajaxShowMessage()
241 * @see $cfg['AjaxEnable']
243 * @name sqlqueryform_submit
245 $("#sqlqueryform.ajax").live('submit', function(event) {
246 event.preventDefault();
247 // remove any div containing a previous error message
248 $('.error').remove();
251 PMA_ajaxShowMessage();
253 if (! $form.find('input:hidden').is('#ajax_request_hidden')) {
254 $form.append('<input type="hidden" id="ajax_request_hidden" name="ajax_request" value="true" />');
257 $.post($(this).attr('action'), $(this).serialize() , function(data) {
258 if(data.success == true) {
259 // fade out previous messages, if any
260 $('.success').fadeOut();
261 $('.sqlquery_message').fadeOut();
262 // show a message that stays on screen
263 $('#sqlqueryform').before(data.message);
264 // and display the query
265 $('<div class="sqlquery_message"></div>')
266 .html(data.sql_query)
267 .insertBefore('#sqlqueryform');
268 // unnecessary div that came from data.sql_query
269 $('.notice').remove();
270 $('#sqlqueryresults').show();
271 // this happens if a USE command was typed
272 if (typeof data.reload != 'undefined') {
273 $form.find('input[name=db]').val(data.db);
274 // need to regenerate the whole upper part
275 $form.find('input[name=ajax_request]').remove();
276 $form.append('<input type="hidden" name="reload" value="true" />');
277 $.post('db_sql.php', $form.serialize(), function(data) {
278 $('body').html(data);
279 }); // end inner post
282 else if (data.success == false ) {
283 // show an error message that stays on screen
284 $('#sqlqueryform').before(data.error);
285 $('#sqlqueryresults').hide();
288 // real results are returned
289 $('#sqlqueryresults').show();
290 $("#sqlqueryresults").html(data);
291 $("#sqlqueryresults").trigger('appendAnchor');
292 $('#togglequerybox').show();
293 if($("#togglequerybox").siblings(":visible").length > 0) {
294 $("#togglequerybox").trigger('click');
299 }) // end SQL Query submit
302 * Ajax Event handlers for Paginating the results table
306 * Paginate when we click any of the navigation buttons
307 * (only if the element has the ajax class, see $cfg['AjaxEnable'])
309 * @name paginate_nav_button_click
310 * @uses PMA_ajaxShowMessage()
311 * @see $cfg['AjaxEnable']
313 $("input[name=navig].ajax").live('click', function(event) {
315 event.preventDefault();
317 PMA_ajaxShowMessage();
320 * @var $the_form Object referring to the form element that paginates the results table
322 var $the_form = $(this).parent("form");
324 $the_form.append('<input type="hidden" name="ajax_request" value="true" />');
326 $.post($the_form.attr('action'), $the_form.serialize(), function(data) {
327 $("#sqlqueryresults").html(data);
328 $("#sqlqueryresults").trigger('appendAnchor');
331 })// end Paginate results table
334 * Paginate results with Page Selector dropdown
336 * @name paginate_dropdown_change
337 * @see $cfg['AjaxEnable']
339 $("#pageselector").live('change', function(event) {
340 var $the_form = $(this).parent("form");
342 if ($(this).hasClass('ajax')) {
343 event.preventDefault();
345 PMA_ajaxShowMessage();
347 $.post($the_form.attr('action'), $the_form.serialize() + '&ajax_request=true', function(data) {
348 $("#sqlqueryresults").html(data);
349 $("#sqlqueryresults").trigger('appendAnchor');
356 })// end Paginate results with Page Selector
359 * Ajax Event handler for sorting the results table
361 * @name table_results_sort_click
362 * @see $cfg['AjaxEnable']
364 $("#table_results.ajax").find("a[title=Sort]").live('click', function(event) {
365 event.preventDefault();
367 PMA_ajaxShowMessage();
371 $.get($anchor.attr('href'), $anchor.serialize() + '&ajax_request=true', function(data) {
372 $("#sqlqueryresults")
374 .trigger('appendAnchor');
376 })//end Sort results table
379 * Ajax Event handler for the display options
381 * @name displayOptionsForm_submit
382 * @see $cfg['AjaxEnable']
384 $("#displayOptionsForm.ajax").live('submit', function(event) {
385 event.preventDefault();
389 $.post($form.attr('action'), $form.serialize() + '&ajax_request=true' , function(data) {
390 $("#sqlqueryresults")
392 .trigger('appendAnchor');
396 //end displayOptionsForm handler
399 * Ajax Event handlers for Inline Editing
403 * On click, replace the fields of current row with an input/textarea
405 * @name inline_edit_start
406 * @see PMA_ajaxShowMessage()
407 * @see getFieldName()
409 $(".inline_edit_anchor").live('click', function(event) {
411 event.preventDefault();
412 $(this).removeClass('inline_edit_anchor').addClass('inline_edit_active');
414 // adding submit and hide buttons to inline edit <td>
415 // for "hide", button the original data to be restored is present in .original_data
416 // looping through all columns or rows, to find the required data and then storing it in an array.
418 var $this_children = $(this).children('span.nowrap').children('a').children('span.nowrap');
419 if (disp_mode != 'vertical'){
420 $this_children.empty();
421 $this_children.text("submit");
424 data_vt = $this_children.html();
425 $this_children.text("submit");
428 if (disp_mode != 'vertical'){
429 $(this).append('<br/><br/><a id="hide">hide</a>');
430 $('#table_results tbody tr td a#hide').click(function(){
431 $this_children = $(this).siblings('span.nowrap').children('a').children('span.nowrap');
432 $this_children.empty();
433 $this_children.text("Inline Edit");
434 var $this_hide = $(this).parent();
435 $this_hide.removeClass("inline_edit_active hover").addClass("inline_edit_anchor");
436 var last_column = $this_hide.siblings().length;
438 for(var i=4; i < last_column; i++){
439 txt[i-4] = $this_hide.siblings("td:eq(" + i + ")").children(' .original_data').text();
441 for (var i=4; i < last_column; i++){
442 $this_hide.siblings("td:eq(" + i + ")").empty();
443 $this_hide.siblings("td:eq(" + i + ")").append(txt[i-4]);
445 $(this).prev().prev().remove();
446 $(this).prev().remove();
451 var rows=$(this).parent().siblings().length;;
453 $(this).append('<br/><br/><a id="hide">hide</a>');
454 $('#table_results tbody tr td a#hide').click(function(){
456 var pos=$(this).parent().index();
457 var $chg_submit=$(this).parent().children('span.nowrap').children('a').children('span.nowrap');
459 $chg_submit.append(data_vt);
461 var $this_row=$(this).parent().parent();
463 if(parseInt(pos)%2==0){
464 $this_row.siblings("tr:eq(3) td:eq(" + pos + ")").removeClass("odd edit_row_anchor row_" + pos + " vpointer vmarker inline_edit_active").addClass("odd edit_row_anchor row_" + pos + " vpointer vmarker inline_edit_anchor");
466 $this_row.siblings("tr:eq(3) td:eq(" + pos + ")").removeClass("odd edit_row_anchor row_" + pos + " vpointer vmarker inline_edit_active hover").addClass("odd edit_row_anchor row_" + pos + " vpointer vmarker inline_edit_anchor");
468 $this_row.siblings("tr:eq(3) td:eq(" + pos + ")").removeClass("even edit_row_anchor row_" + pos + " vpointer vmarker inline_edit_active").addClass("even edit_row_anchor row_" + pos + " vpointer vmarker inline_edit_anchor");
470 $this_row.siblings("tr:eq(3) td:eq(" + pos + ")").removeClass("even edit_row_anchor row_" + pos + " vpointer vmarker inline_edit_active hover").addClass("even edit_row_anchor row_" + pos + " vpointer vmarker inline_edit_anchor");
474 for( var i=6;i<=rows+2;i++){
475 txt[i-6]=$this_row.siblings("tr:eq("+i+") td:eq("+pos+") span.original_data").text();
477 for (var i=6;i<=rows+2;i++){
478 $this_row.siblings("tr:eq("+i+") td:eq("+pos+")").empty();
479 $this_row.siblings("tr:eq("+i+") td:eq("+pos+")").append(txt[i-6]);
481 $(this).prev().remove();
482 $(this).prev().remove();
488 // Initialize some variables
489 if(disp_mode == 'vertical') {
491 * @var this_row_index Index of the current <td> in the parent <tr>
492 * Current <td> is the inline edit anchor.
494 var this_row_index = $(this).index();
496 * @var $input_siblings Object referring to all inline editable events from same row
498 var $input_siblings = $(this).parents('tbody').find('tr').find('.inline_edit:nth('+this_row_index+')');
500 * @var where_clause String containing the WHERE clause to select this row
502 var where_clause = $(this).parents('tbody').find('tr').find('.where_clause:nth('+this_row_index+')').val();
506 var this_row_index = $(this).parent().index();
507 var $input_siblings = $(this).parent('tr').find('.inline_edit');
508 var where_clause = $(this).parent('tr').find('.where_clause').val();
511 $input_siblings.each(function() {
514 * @var data_value Current value of this field
516 var data_value = $(this).html();
518 // We need to retrieve the value from the server for truncated/relation fields
519 // Find the field name
522 * @var this_field Object referring to this field (<td>)
524 var $this_field = $(this);
526 * @var field_name String containing the name of this field.
527 * @see getFieldName()
529 var field_name = getFieldName($this_field, disp_mode);
531 * @var relation_curr_value String current value of the field (for fields that are foreign keyed).
533 var relation_curr_value = $this_field.find('a').text();
535 * @var curr_value String current value of the field (for fields that are of type enum or set).
537 var curr_value = $this_field.text();
539 if($this_field.is(':not(.not_null)')){
540 // add a checkbox to mark null for all the field that are nullable.
541 $this_field.html('<div class="null_div">Null :<input type="checkbox" class="checkbox_null_'+ field_name + '_' + this_row_index +'"></div>');
542 // check the 'checkbox_null_<field_name>_<row_index>' if the corresponding value is null
543 if($this_field.is('.null')) {
544 $('.checkbox_null_' + field_name + '_' + this_row_index).attr('checked', true);
547 // if the select/editor is changed un-check the 'checkbox_null_<field_name>_<row_index>'.
548 if ($this_field.is('.enum, .set')) {
549 $this_field.find('select').live('change', function(e) {
550 $('.checkbox_null_' + field_name + '_' + this_row_index).attr('checked', false);
552 } else if ($this_field.is('.relation')) {
553 $this_field.find('select').live('change', function(e) {
554 $('.checkbox_null_' + field_name + '_' + this_row_index).attr('checked', false);
556 $this_field.find('.browse_foreign').live('click', function(e) {
557 $('.checkbox_null_' + field_name + '_' + this_row_index).attr('checked', false);
560 $this_field.find('textarea').live('keypress', function(e) {
561 $('.checkbox_null_' + field_name + '_' + this_row_index).attr('checked', false);
565 // if 'chechbox_null_<field_name>_<row_index>' is clicked empty the corresponding select/editor.
566 $('.checkbox_null_' + field_name + '_' + this_row_index).bind('click', function(e) {
567 if ($this_field.is('.enum')) {
568 $this_field.find('select').attr('value', '');
569 } else if ($this_field.is('.set')) {
570 $this_field.find('select').find('option').each(function() {
571 var $option = $(this);
572 $option.attr('selected', false);
574 } else if ($this_field.is('.relation')) {
575 // if the dropdown is there to select the foreign value
576 if ($this_field.find('select').length > 0) {
577 $this_field.find('select').attr('value', '');
578 // if foriegn value is selected by browsing foreing values
580 $this_field.find('span.curr_value').empty();
583 $this_field.find('textarea').val('');
588 $this_field.html('<div class="null_div"></div>');
591 // In each input sibling, wrap the current value in a textarea
592 // and store the current value in a hidden span
593 if($this_field.is(':not(.truncated, .transformed, .relation, .enum, .set, .null)')) {
594 // handle non-truncated, non-transformed, non-relation values
595 // We don't need to get any more data, just wrap the value
596 $this_field.append('<textarea>'+data_value+'</textarea>');
597 $this_field.append('<span class="original_data">'+data_value+'</span>');
598 $(".original_data").hide();
600 else if($this_field.is('.truncated, .transformed')) {
602 //handle truncated/transformed values values
605 * @var sql_query String containing the SQL query used to retrieve value of truncated/transformed data
607 var sql_query = 'SELECT ' + field_name + ' FROM ' + window.parent.table + ' WHERE ' + where_clause;
609 // Make the Ajax call and get the data, wrap it and insert it
611 'token' : window.parent.token,
612 'db' : window.parent.db,
613 'ajax_request' : true,
614 'sql_query' : sql_query,
617 if(data.success == true) {
618 $this_field.append('<textarea>'+data.value+'</textarea>');
619 $this_field.append('<span class="original_data">'+data_value+'</span>');
620 $(".original_data").hide();
623 PMA_ajaxShowMessage(data.error);
627 else if($this_field.is('.relation')) {
632 * @var post_params Object containing parameters for the POST request
635 'ajax_request' : true,
636 'get_relational_values' : true,
637 'db' : window.parent.db,
638 'table' : window.parent.table,
639 'column' : field_name,
640 'token' : window.parent.token,
641 'curr_value' : relation_curr_value
644 $.post('sql.php', post_params, function(data) {
645 $this_field.append(data.dropdown);
646 $this_field.append('<span class="original_data">'+data_value+'</span>');
647 $(".original_data").hide();
650 else if($this_field.is('.enum')) {
655 * @var post_params Object containing parameters for the POST request
658 'ajax_request' : true,
659 'get_enum_values' : true,
660 'db' : window.parent.db,
661 'table' : window.parent.table,
662 'column' : field_name,
663 'token' : window.parent.token,
664 'curr_value' : curr_value
667 $.post('sql.php', post_params, function(data) {
668 $this_field.append(data.dropdown);
669 $this_field.append('<span class="original_data">'+data_value+'</span>');
670 $(".original_data").hide();
673 else if($this_field.is('.set')) {
678 * @var post_params Object containing parameters for the POST request
681 'ajax_request' : true,
682 'get_set_values' : true,
683 'db' : window.parent.db,
684 'table' : window.parent.table,
685 'column' : field_name,
686 'token' : window.parent.token,
687 'curr_value' : curr_value
690 $.post('sql.php', post_params, function(data) {
691 $this_field.append(data.select);
692 $this_field.append('<span class="original_data">'+data_value+'</span>');
693 $(".original_data").hide();
696 else if($this_field.is('.null')) {
698 $this_field.append('<textarea></textarea>');
699 $this_field.append('<span class="original_data">NULL</span>');
700 $(".original_data").hide();
703 }) // End On click, replace the current field with an input/textarea
706 * After editing, clicking again should post data
709 * @name inline_edit_save
710 * @see PMA_ajaxShowMessage()
711 * @see getFieldName()
713 $(".inline_edit_active span a").live('click', function(event) {
716 event.preventDefault();
719 * @var $this_td Object referring to the td containing the
720 * "Inline Edit" link that was clicked to save the row that is
724 var $this_td = $(this).parent().parent();
725 var $test_element = ''; // to test the presence of a element
727 // Initialize variables
728 if(disp_mode == 'vertical') {
730 * @var this_td_index Index of the current <td> in the parent <tr>
731 * Current <td> is the inline edit anchor.
733 var this_td_index = $this_td.index();
735 * @var $input_siblings Object referring to all inline editable events from same row
737 var $input_siblings = $this_td.parents('tbody').find('tr').find('.inline_edit:nth('+this_td_index+')');
739 * @var where_clause String containing the WHERE clause to select this row
741 var where_clause = $this_td.parents('tbody').find('tr').find('.where_clause:nth('+this_td_index+')').val();
743 var $input_siblings = $this_td.parent('tr').find('.inline_edit');
744 var where_clause = $this_td.parent('tr').find('.where_clause').val();
748 * @var nonunique Boolean, whether this row is unique or not
750 if($this_td.is('.nonunique')) {
757 // Collect values of all fields to submit, we don't know which changed
759 * @var relation_fields Array containing the name/value pairs of relational fields
761 var relation_fields = {};
763 * @var transform_fields Array containing the name/value pairs for transformed fields
765 var transform_fields = {};
767 * @var transformation_fields Boolean, if there are any transformed fields in this row
769 var transformation_fields = false;
772 * @var sql_query String containing the SQL query to update this row
774 var sql_query = 'UPDATE ' + window.parent.table + ' SET ';
776 $input_siblings.each(function() {
779 * @var this_field Object referring to this field (<td>)
781 var $this_field = $(this);
783 * @var field_name String containing the name of this field.
784 * @see getFieldName()
786 var field_name = getFieldName($this_field, disp_mode);
789 * @var this_field_params Array temporary storage for the name/value of current field
791 var this_field_params = {};
793 if($this_field.is('.transformed')) {
794 transformation_fields = true;
797 * @var is_null String capturing whether 'checkbox_null_<field_name>_<row_index>' is checked.
799 var is_null = $this_field.find('input:checkbox').is(':checked');
803 sql_query += ' ' + field_name + "=NULL , ";
805 if($this_field.is(":not(.relation, .enum, .set)")) {
806 this_field_params[field_name] = $this_field.find('textarea').val();
807 if($this_field.is('.transformed')) {
808 $.extend(transform_fields, this_field_params);
810 } else if ($this_field.is('.set')) {
811 $test_element = $this_field.find('select');
812 this_field_params[field_name] = $test_element.map(function(){
813 return $(this).val();
816 // results from a drop-down
817 $test_element = $this_field.find('select');
818 if ($test_element.length != 0) {
819 this_field_params[field_name] = $test_element.val();
822 // results from Browse foreign value
823 $test_element = $this_field.find('span.curr_value');
824 if ($test_element.length != 0) {
825 this_field_params[field_name] = $test_element.text();
828 if($this_field.is('.relation')) {
829 $.extend(relation_fields, this_field_params);
832 sql_query += ' ' + field_name + "='" + this_field_params[field_name].replace(/'/g, "''") + "' , ";
836 //Remove the last ',' appended in the above loop
837 sql_query = sql_query.replace(/,\s$/, '');
838 sql_query += ' WHERE ' + PMA_urldecode(where_clause);
841 * @var rel_fields_list String, url encoded representation of {@link relations_fields}
843 var rel_fields_list = $.param(relation_fields);
846 * @var transform_fields_list String, url encoded representation of {@link transform_fields}
848 var transform_fields_list = $.param(transform_fields);
850 // Make the Ajax post after setting all parameters
852 * @var post_params Object containing parameters for the POST request
854 var post_params = {'ajax_request' : true,
855 'sql_query' : sql_query,
856 'disp_direction' : disp_mode,
857 'token' : window.parent.token,
858 'db' : window.parent.db,
859 'table' : window.parent.table,
860 'clause_is_unique' : nonunique,
861 'where_clause' : where_clause,
862 'rel_fields_list' : rel_fields_list,
863 'do_transformations' : transformation_fields,
864 'transform_fields_list' : transform_fields_list,
866 'submit_type' : 'save'
869 // if inline_edit is successful, we need to go back to default view
870 var $del_hide=$(this).parent();
871 var $chg_submit=$(this);
873 $.post('tbl_replace.php', post_params, function(data) {
874 if(data.success == true) {
875 // deleting the hide button if my query was successful
876 // remove <br><br><a> tags
877 for ( var i=0;i<=2;i++) { $del_hide.next().remove(); }
878 if(disp_mode!='vertical'){
880 $chg_submit.text("Inline Edit");
883 $chg_submit.children('span.nowrap').empty();
884 $chg_submit.children('span.nowrap').append(data_vt);
887 PMA_ajaxShowMessage(data.message);
888 $this_td.removeClass('inline_edit_active').addClass('inline_edit_anchor');
890 $input_siblings.each(function() {
891 // Inline edit post has been successful.
892 $this_sibling = $(this);
894 var is_null = $this_sibling.find('input:checkbox').is(':checked');
896 $this_sibling.html('NULL');
897 $this_sibling.addClass('null');
899 $this_sibling.removeClass('null');
900 if($this_sibling.is(':not(.relation, .enum, .set)')) {
902 * @var new_html String containing value of the data field after edit
904 var new_html = $this_sibling.find('textarea').val();
906 if($this_sibling.is('.transformed')) {
907 var field_name = getFieldName($this_sibling, disp_mode);
908 $.each(data.transformations, function(key, value) {
909 if(key == field_name) {
910 if($this_sibling.is('.text_plain, .application_octetstream')) {
915 var new_value = $this_sibling.find('textarea').val();
916 new_html = $(value).append(new_value);
926 $test_element = $this_sibling.find('select');
927 if ($test_element.length != 0) {
928 new_value = $test_element.val();
931 $test_element = $this_sibling.find('span.curr_value');
932 if ($test_element.length != 0) {
933 new_value = $test_element.text();
936 if($this_sibling.is('.relation')) {
937 var field_name = getFieldName($this_sibling, disp_mode);
938 $.each(data.relations, function(key, value) {
939 if(key == field_name) {
940 new_html = $(value).append(new_value);
944 } else if ($this_sibling.is('.enum')) {
945 new_html = new_value;
946 } else if ($this_sibling.is('.set')) {
947 if (new_value != null) {
948 $.each(new_value, function(key, value) {
949 new_html = new_html + value + ',';
951 new_html = new_html.substring(0, new_html.length-1);
955 $this_sibling.html(new_html);
960 PMA_ajaxShowMessage(data.error);
963 }) // End After editing, clicking again should post data
964 }, 'top.frame_content') // end $(document).ready()
967 * Starting from some th, change the class of all td under it
969 function PMA_changeClassForColumn($this_th, newclass) {
970 // index 0 is the th containing the big T
971 var th_index = $this_th.index();
972 // .eq() is zero-based
974 var $tr_with_data = $this_th.closest('table').find('tbody tr ').has('td.data');
975 $tr_with_data.each(function() {
976 $(this).find('td.data:eq('+th_index+')').toggleClass(newclass);
980 $(document).ready(function() {
982 $('.browse_foreign').live('click', function(e) {
984 window.open(this.href, 'foreigners', 'width=640,height=240,scrollbars=yes,resizable=yes');
986 $anchor.addClass('browse_foreign_clicked');
991 * vertical column highlighting in horizontal mode when hovering over the column header
993 $('.column_heading').live('hover', function() {
994 PMA_changeClassForColumn($(this), 'hover');
998 * vertical column marking in horizontal mode when clicking the column header
1000 $('.column_heading').live('click', function() {
1001 PMA_changeClassForColumn($(this), 'marked');