Deactivate these messages as we are currently in message freeze for 3.4
[phpmyadmin-themes.git] / js / sql.js
blob34e1e74c0b07ea3c6652ff3edf2f2220ffb514ed
1 /* vim: set expandtab sw=4 ts=4 sts=4: */
2 /**
3  * @fileoverview    functions used wherever an sql query form is used
4  *
5  * @requires    jQuery
6  * @requires    js/functions.js
7  *
8  */
10 /**
11  * decode a string URL_encoded
12  *
13  * @param string str
14  * @return string the URL-decoded string
15  */
16 function PMA_urldecode(str) {
17     return decodeURIComponent(str.replace(/\+/g, '%20'));
20 /**
21  * Get the field name for the current field.  Required to construct the query
22  * for inline editing
23  *
24  * @param   $this_field  jQuery object that points to the current field's tr
25  * @param   disp_mode    string
26  */
27 function getFieldName($this_field, disp_mode) {
29     if(disp_mode == 'vertical') {
30         var field_name = $this_field.siblings('th').find('a').text();
31         // happens when just one row (headings contain no a)
32         if ("" == field_name) {
33             field_name = $this_field.siblings('th').text();
34         }
35     }
36     else {
37         var this_field_index = $this_field.index();
38         // ltr or rtl direction does not impact how the DOM was generated
39         //
40         // 5 columns to account for the checkbox, edit, appended inline edit, copy and delete anchors but index is zero-based so substract 4
41         var field_name = $('#table_results').find('thead').find('th:nth('+ (this_field_index-4 )+') a').text();
42         // happens when just one row (headings contain no a)
43         if ("" == field_name) {
44             field_name = $('#table_results').find('thead').find('th:nth('+ (this_field_index-4 )+')').text();
45         }
46     }
48     field_name = $.trim(field_name);
50     return field_name;
53 /**
54  * The function that iterates over each row in the table_results and appends a
55  * new inline edit anchor to each table row.
56  *
57  */
58 function appendInlineAnchor() {
59     var disp_mode = $("#top_direction_dropdown").val();
61     if (disp_mode == 'vertical') {
62         // there can be one or two tr containing this class, depending
63         // on the ModifyDeleteAtLeft and ModifyDeleteAtRight cfg parameters
64         $('#table_results tr')
65             .find('.edit_row_anchor')
66             .removeClass('.edit_row_anchor')
67             .parent().each(function() {
68             var $this_tr = $(this);
69             var $cloned_tr = $this_tr.clone();
71             var $img_object = $cloned_tr.find('img:first').attr('title', PMA_messages['strInlineEdit']);
72             if ($img_object.length != 0) {
73                 var img_src = $img_object.attr('src').replace(/b_edit/,'b_inline_edit');
74                 $img_object.attr('src', img_src);
75             }
77             $cloned_tr.find('td')
78              .addClass('inline_edit_anchor')
79              .find('a').attr('href', '#')
80              .find('span')
81              .text(' ' + PMA_messages['strInlineEdit'])
82              .prepend($img_object);
84             $cloned_tr.insertAfter($this_tr);
85         });
87         $('#rowsDeleteForm').find('tbody').find('th').each(function() {
88             var $this_th = $(this);
89             if ($this_th.attr('rowspan') == 4) {
90                 $this_th.attr('rowspan', '5');
91             }
92         });
93     }
94     else {
95         // horizontal mode
96         $('.edit_row_anchor').each(function() {
98             var $this_td = $(this);
99             $this_td.removeClass('edit_row_anchor');
101             var $cloned_anchor = $this_td.clone();
103             var $img_object = $cloned_anchor.find('img').attr('title', PMA_messages['strInlineEdit']);
104             if ($img_object.length != 0) {
105                 var img_src = $img_object.attr('src').replace(/b_edit/,'b_inline_edit');
106                 $img_object.attr('src', img_src);
107                 $cloned_anchor
108                  .find('a').attr('href', '#')
109                  .find('span')
110                  .text(' ' + PMA_messages['strInlineEdit']);
111                 $cloned_anchor
112                  .find('span')
113                  .first()
114                  .prepend($img_object);
115             } else {
116                 // the link was too big so <input type="image"> is there
117                 $img_object = $cloned_anchor.find('input:image').attr('title', PMA_messages['strInlineEdit']);
118                 var img_src = $img_object.attr('src').replace(/b_edit/,'b_inline_edit');
119                 $img_object.attr('src', img_src);
120                 $cloned_anchor
121                  .find('.clickprevimage')
122                  .text(' ' + PMA_messages['strInlineEdit']);
123             }
125             $cloned_anchor
126              .addClass('inline_edit_anchor');
128             $this_td.after($cloned_anchor);
129         });
131         $('#rowsDeleteForm').find('thead, tbody').find('th').each(function() {
132             var $this_th = $(this);
133             if ($this_th.attr('colspan') == 4) {
134                 $this_th.attr('colspan', '5');
135             }
136         });
137     }
140 /**#@+
141  * @namespace   jQuery
142  */
145  * @description <p>Ajax scripts for sql and browse pages</p>
147  * Actions ajaxified here:
148  * <ul>
149  * <li>Retrieve results of an SQL query</li>
150  * <li>Paginate the results table</li>
151  * <li>Sort the results table</li>
152  * <li>Change table according to display options</li>
153  * <li>Inline editing of data</li>
154  * </ul>
156  * @name        document.ready
157  * @memberOf    jQuery
158  */
159 $(document).ready(function() {
161     /**
162      * Set a parameter for all Ajax queries made on this page.  Don't let the
163      * web server serve cached pages
164      */
165     $.ajaxSetup({
166         cache: 'false'
167     });
169     /**
170      * current value of the direction in which the table is displayed
171      * @type    String
172      * @fieldOf jQuery
173      * @name    disp_mode
174      */
175     var disp_mode = $("#top_direction_dropdown").val();
177     /**
178      * Update value of {@link jQuery.disp_mode} everytime the direction dropdown changes value
179      * @memberOf    jQuery
180      * @name        direction_dropdown_change
181      */
182     $("#top_direction_dropdown, #bottom_direction_dropdown").live('change', function(event) {
183         disp_mode = $(this).val();
184     })
186     /**
187      * Attach the {@link appendInlineAnchor} function to a custom event, which
188      * will be triggered manually everytime the table of results is reloaded
189      * @memberOf    jQuery
190      */
191     $("#sqlqueryresults").live('appendAnchor',function() {
192         appendInlineAnchor();
193     })
195     /**
196      * Trigger the appendAnchor event to prepare the first table for inline edit
197      * (see $GLOBALS['cfg']['AjaxEnable'])
198      * @memberOf    jQuery
199      * @name        sqlqueryresults_trigger
200      */
201     $("#sqlqueryresults.ajax").trigger('appendAnchor');
203     /**
204      * Append the "Show/Hide query box" message to the query input form
205      *
206      * @memberOf jQuery
207      * @name    appendToggleSpan
208      */
209     // do not add this link more than once
210     if (! $('#sqlqueryform').find('a').is('#togglequerybox')) {
211         $('<a id="togglequerybox"></a>')
212         .html(PMA_messages['strHideQueryBox'])
213         .appendTo("#sqlqueryform")
214         // initially hidden because at this point, nothing else
215         // appears under the link
216         .hide();
218         // Attach the toggling of the query box visibility to a click
219         $("#togglequerybox").bind('click', function() {
220             var $link = $(this)
221             $link.siblings().slideToggle("fast");
222             if ($link.text() == PMA_messages['strHideQueryBox']) {
223                 $link.text(PMA_messages['strShowQueryBox']);
224                 // cheap trick to add a spacer between the menu tabs
225                 // and "Show query box"; feel free to improve!
226                 $('#togglequerybox_spacer').remove();
227                 $link.before('<br id="togglequerybox_spacer" />');
228             } else {
229                 $link.text(PMA_messages['strHideQueryBox']);
230             }
231             // avoid default click action
232             return false;
233         })
234     }
236     /**
237      * Ajax Event handler for 'SQL Query Submit'
238      *
239      * @see         PMA_ajaxShowMessage()
240      * @see         $cfg['AjaxEnable']
241      * @memberOf    jQuery
242      * @name        sqlqueryform_submit
243      */
244     $("#sqlqueryform.ajax").live('submit', function(event) {
245         event.preventDefault();
246         // remove any div containing a previous error message
247         $('.error').remove();
249         $form = $(this);
250         PMA_ajaxShowMessage();
252         if (! $form.find('input:hidden').is('#ajax_request_hidden')) {
253             $form.append('<input type="hidden" id="ajax_request_hidden" name="ajax_request" value="true" />');
254         }
256         $.post($(this).attr('action'), $(this).serialize() , function(data) {
257             if(data.success == true) {
258                 // fade out previous messages, if any
259                 $('.success').fadeOut();
260                 $('.sqlquery_message').fadeOut();
261                 // show a message that stays on screen
262                 $('#sqlqueryform').before(data.message);
263                 // and display the query
264                 $('<div class="sqlquery_message"></div>')
265                  .html(data.sql_query)
266                  .insertBefore('#sqlqueryform');
267                 // unnecessary div that came from data.sql_query
268                 $('.notice').remove();
269                 $('#sqlqueryresults').show();
270                 // this happens if a USE command was typed
271                 if (typeof data.reload != 'undefined') {
272                     $form.find('input[name=db]').val(data.db);
273                     // need to regenerate the whole upper part
274                     $form.find('input[name=ajax_request]').remove();
275                     $form.append('<input type="hidden" name="reload" value="true" />');
276                     $.post('db_sql.php', $form.serialize(), function(data) {
277                         $('body').html(data);
278                     }); // end inner post
279                 }
280             }
281             else if (data.success == false ) {
282                 // show an error message that stays on screen
283                 $('#sqlqueryform').before(data.error);
284                 $('#sqlqueryresults').hide();
285             }
286             else {
287                 // real results are returned
288                 $('#sqlqueryresults').show();
289                 $("#sqlqueryresults").html(data);
290                 $("#sqlqueryresults").trigger('appendAnchor');
291                 $('#togglequerybox').show();
292                 if($("#togglequerybox").siblings(":visible").length > 0) {
293                     $("#togglequerybox").trigger('click');
294                 }
295                 PMA_init_slider();
296             }
297         }) // end $.post()
298     }) // end SQL Query submit
300     /**
301      * Ajax Event handlers for Paginating the results table
302      */
304     /**
305      * Paginate when we click any of the navigation buttons
306      * (only if the element has the ajax class, see $cfg['AjaxEnable'])
307      * @memberOf    jQuery
308      * @name        paginate_nav_button_click
309      * @uses        PMA_ajaxShowMessage()
310      * @see         $cfg['AjaxEnable']
311      */
312     $("input[name=navig].ajax").live('click', function(event) {
313         /** @lends jQuery */
314         event.preventDefault();
316         PMA_ajaxShowMessage();
318         /**
319          * @var $the_form    Object referring to the form element that paginates the results table
320          */
321         var $the_form = $(this).parent("form");
323         $the_form.append('<input type="hidden" name="ajax_request" value="true" />');
325         $.post($the_form.attr('action'), $the_form.serialize(), function(data) {
326             $("#sqlqueryresults").html(data);
327             $("#sqlqueryresults").trigger('appendAnchor');
328             PMA_init_slider();
329         }) // end $.post()
330     })// end Paginate results table
332     /**
333      * Paginate results with Page Selector dropdown
334      * @memberOf    jQuery
335      * @name        paginate_dropdown_change
336      * @see         $cfg['AjaxEnable']
337      */
338     $("#pageselector").live('change', function(event) {
339         var $the_form = $(this).parent("form");
341         if ($(this).hasClass('ajax')) {
342             event.preventDefault();
344             PMA_ajaxShowMessage();
346             $.post($the_form.attr('action'), $the_form.serialize() + '&ajax_request=true', function(data) {
347                 $("#sqlqueryresults").html(data);
348                 $("#sqlqueryresults").trigger('appendAnchor');
349                 PMA_init_slider();
350             }) // end $.post()
351         } else {
352             $the_form.submit();
353         }
355     })// end Paginate results with Page Selector
357     /**
358      * Ajax Event handler for sorting the results table
359      * @memberOf    jQuery
360      * @name        table_results_sort_click
361      * @see         $cfg['AjaxEnable']
362      */
363     $("#table_results.ajax").find("a[title=Sort]").live('click', function(event) {
364         event.preventDefault();
366         PMA_ajaxShowMessage();
368         $anchor = $(this);
370         $.get($anchor.attr('href'), $anchor.serialize() + '&ajax_request=true', function(data) {
371             $("#sqlqueryresults")
372              .html(data)
373              .trigger('appendAnchor');
374         }) // end $.get()
375     })//end Sort results table
377     /**
378      * Ajax Event handler for the display options
379      * @memberOf    jQuery
380      * @name        displayOptionsForm_submit
381      * @see         $cfg['AjaxEnable']
382      */
383     $("#displayOptionsForm.ajax").live('submit', function(event) {
384         event.preventDefault();
386         $form = $(this);
388         $.post($form.attr('action'), $form.serialize() + '&ajax_request=true' , function(data) {
389             $("#sqlqueryresults")
390              .html(data)
391              .trigger('appendAnchor');
392             PMA_init_slider();
393         }) // end $.post()
394     })
395     //end displayOptionsForm handler
397     /**
398      * Ajax Event handlers for Inline Editing
399      */
401     /**
402      * On click, replace the fields of current row with an input/textarea
403      * @memberOf    jQuery
404      * @name        inline_edit_start
405      * @see         PMA_ajaxShowMessage()
406      * @see         getFieldName()
407      */
408     $(".inline_edit_anchor").live('click', function(event) {
409         /** @lends jQuery */
410         event.preventDefault();
412         $(this).removeClass('inline_edit_anchor').addClass('inline_edit_active');
414         // Initialize some variables
415         if(disp_mode == 'vertical') {
416             /**
417              * @var this_row_index  Index of the current <td> in the parent <tr>
418              *                      Current <td> is the inline edit anchor.
419              */
420             var this_row_index = $(this).index();
421             /**
422              * @var $input_siblings  Object referring to all inline editable events from same row
423              */
424             var $input_siblings = $(this).parents('tbody').find('tr').find('.inline_edit:nth('+this_row_index+')');
425             /**
426              * @var where_clause    String containing the WHERE clause to select this row
427              */
428             var where_clause = $(this).parents('tbody').find('tr').find('.where_clause:nth('+this_row_index+')').val();
429         }
430         // horizontal mode
431         else {
432             var this_row_index = $(this).parent().index();
433             var $input_siblings = $(this).parent('tr').find('.inline_edit');
434             var where_clause = $(this).parent('tr').find('.where_clause').val();
435         }
437         $input_siblings.each(function() {
438             /** @lends jQuery */
439             /**
440              * @var data_value  Current value of this field
441              */
442             var data_value = $(this).html();
444             // We need to retrieve the value from the server for truncated/relation fields
445             // Find the field name
447             /**
448              * @var this_field  Object referring to this field (<td>)
449              */
450             var $this_field = $(this);
451             /**
452              * @var field_name  String containing the name of this field.
453              * @see getFieldName()
454              */
455             var field_name = getFieldName($this_field, disp_mode);
456             /**
457              * @var relation_curr_value String current value of the field (for fields that are foreign keyed).
458              */
459             var relation_curr_value = $this_field.find('a').text();
460             /**
461              * @var enum_curr_value String current value of the field (for fields that are of type enum).
462              */
463             var enum_curr_value = $this_field.text();
465             if($this_field.is(':not(.not_null)')){
466                 // add a checkbox to mark null for all the field that are nullable.
467                 $this_field.html('<div class="null_div">Null :<input type="checkbox" class="checkbox_null_'+ field_name + '_' + this_row_index +'"></div>');
468                 // check the 'checkbox_null_<field_name>_<row_index>' if the corresponding value is null
469                 if($this_field.is('.null')) {
470                     $('.checkbox_null_' + field_name + '_' + this_row_index).attr('checked', true);
471                 }
473                 // if the select/editor is changed un-check the 'checkbox_null_<field_name>_<row_index>'.
474                 if ($this_field.is('.enum, .set')) {
475                     $this_field.find('select').live('change', function(e) {
476                         $('.checkbox_null_' + field_name + '_' + this_row_index).attr('checked', false);
477                     })
478                 } else if ($this_field.is('.relation')) {
479                     $this_field.find('select').live('change', function(e) {
480                         $('.checkbox_null_' + field_name + '_' + this_row_index).attr('checked', false);
481                     })
482                     $this_field.find('.browse_foreign').live('click', function(e) {
483                         $('.checkbox_null_' + field_name + '_' + this_row_index).attr('checked', false);
484                     })
485                 } else {
486                     $this_field.find('textarea').live('keypress', function(e) {
487                         $('.checkbox_null_' + field_name + '_' + this_row_index).attr('checked', false);
488                     })
489                 }
491                 // if 'chechbox_null_<field_name>_<row_index>' is clicked empty the corresponding select/editor.
492                 $('.checkbox_null_' + field_name + '_' + this_row_index).bind('click', function(e) {
493                     if ($this_field.is('.enum, .set')) {
494                         $this_field.find('select').attr('value', '');
495                     } else if ($this_field.is('.relation')) {
496                         // if the dropdown is there to select the foreign value
497                         if ($this_field.find('select').length > 0) {
498                             $this_field.find('select').attr('value', '');
499                         // if foriegn value is selected by browsing foreing values
500                         } else {
501                             $this_field.find('span.curr_value').empty();
502                         }
503                     } else {
504                         $this_field.find('textarea').val('');
505                     }
506                 })
508             } else {
509                 $this_field.html('<div class="null_div"></div>');
510             }
512             // In each input sibling, wrap the current value in a textarea
513             // and store the current value in a hidden span
514             if($this_field.is(':not(.truncated, .transformed, .relation, .enum, .null)')) {
515                 // handle non-truncated, non-transformed, non-relation values
516                 // We don't need to get any more data, just wrap the value
517                 $this_field.append('<textarea>'+data_value+'</textarea>');
518                 $this_field.append('<span class="original_data">'+data_value+'</span>');
519                 $(".original_data").hide();
520             }
521             else if($this_field.is('.truncated, .transformed')) {
522                 /** @lends jQuery */
523                 //handle truncated/transformed values values
525                 /**
526                  * @var sql_query   String containing the SQL query used to retrieve value of truncated/transformed data
527                  */
528                 var sql_query = 'SELECT ' + field_name + ' FROM ' + window.parent.table + ' WHERE ' + where_clause;
530                 // Make the Ajax call and get the data, wrap it and insert it
531                 $.post('sql.php', {
532                     'token' : window.parent.token,
533                     'db' : window.parent.db,
534                     'ajax_request' : true,
535                     'sql_query' : sql_query,
536                     'inline_edit' : true
537                 }, function(data) {
538                     if(data.success == true) {
539                         $this_field.append('<textarea>'+data.value+'</textarea>');
540                         $this_field.append('<span class="original_data">'+data_value+'</span>');
541                         $(".original_data").hide();
542                     }
543                     else {
544                         PMA_ajaxShowMessage(data.error);
545                     }
546                 }) // end $.post()
547             }
548             else if($this_field.is('.relation')) {
549                 /** @lends jQuery */
550                 //handle relations
552                 /**
553                  * @var post_params Object containing parameters for the POST request
554                  */
555                 var post_params = {
556                         'ajax_request' : true,
557                         'get_relational_values' : true,
558                         'db' : window.parent.db,
559                         'table' : window.parent.table,
560                         'column' : field_name,
561                         'token' : window.parent.token,
562                         'curr_value' : relation_curr_value
563                 }
565                 $.post('sql.php', post_params, function(data) {
566                     $this_field.append(data.dropdown);
567                     $this_field.append('<span class="original_data">'+data_value+'</span>');
568                     $(".original_data").hide();
569                 }) // end $.post()
570             }
571             else if($this_field.is('.enum')) {
572                 /** @lends jQuery */
573                 //handle enum fields
575                 /**
576                  * @var post_params Object containing parameters for the POST request
577                  */
578                 var post_params = {
579                         'ajax_request' : true,
580                         'get_enum_values' : true,
581                         'db' : window.parent.db,
582                         'table' : window.parent.table,
583                         'column' : field_name,
584                         'token' : window.parent.token,
585                         'curr_value' : enum_curr_value
586                 }
588                 $.post('sql.php', post_params, function(data) {
589                     $this_field.append(data.dropdown);
590                     $this_field.append('<span class="original_data">'+data_value+'</span>');
591                     $(".original_data").hide();
592                 }) // end $.post()
593             }
594             else if($this_field.is('.null')) {
595                 //handle null fields
596                 $this_field.append('<textarea></textarea>');
597                 $this_field.append('<span class="original_data">NULL</span>');
598                 $(".original_data").hide();
599             }
600         })
601     }) // End On click, replace the current field with an input/textarea
603     /**
604      * After editing, clicking again should post data
605      *
606      * @memberOf    jQuery
607      * @name        inline_edit_save
608      * @see         PMA_ajaxShowMessage()
609      * @see         getFieldName()
610      */
611     $(".inline_edit_active").live('click', function(event) {
612         /** @lends jQuery */
613         event.preventDefault();
615         /**
616          * @var $this_td    Object referring to the td containing the
617          * "Inline Edit" link that was clicked to save the row that is
618          * being edited
619          *
620          */
621         var $this_td = $(this);
623         var $test_element = ''; // to test the presence of a element
625         // Initialize variables
626         if(disp_mode == 'vertical') {
627             /**
628              * @var this_td_index  Index of the current <td> in the parent <tr>
629              *                      Current <td> is the inline edit anchor.
630              */
631             var this_td_index = $this_td.index();
632             /**
633              * @var $input_siblings  Object referring to all inline editable events from same row
634              */
635             var $input_siblings = $this_td.parents('tbody').find('tr').find('.inline_edit:nth('+this_td_index+')');
636             /**
637              * @var where_clause    String containing the WHERE clause to select this row
638              */
639             var where_clause = $this_td.parents('tbody').find('tr').find('.where_clause:nth('+this_td_index+')').val();
640         }
641         else {
642             var $input_siblings = $this_td.parent('tr').find('.inline_edit');
643             var where_clause = $this_td.parent('tr').find('.where_clause').val();
644         }
646         /**
647          * @var nonunique   Boolean, whether this row is unique or not
648          */
649         if($this_td.is('.nonunique')) {
650             var nonunique = 0;
651         }
652         else {
653             var nonunique = 1;
654         }
656         // Collect values of all fields to submit, we don't know which changed
657         /**
658          * @var relation_fields Array containing the name/value pairs of relational fields
659          */
660         var relation_fields = {};
661         /**
662          * @var transform_fields    Array containing the name/value pairs for transformed fields
663          */
664         var transform_fields = {};
665         /**
666          * @var transformation_fields   Boolean, if there are any transformed fields in this row
667          */
668         var transformation_fields = false;
670         /**
671          * @var sql_query String containing the SQL query to update this row
672          */
673         var sql_query = 'UPDATE ' + window.parent.table + ' SET ';
675         $input_siblings.each(function() {
676             /** @lends jQuery */
677             /**
678              * @var this_field  Object referring to this field (<td>)
679              */
680             var $this_field = $(this);
681             /**
682              * @var field_name  String containing the name of this field.
683              * @see getFieldName()
684              */
685             var field_name = getFieldName($this_field, disp_mode);
687             /**
688              * @var this_field_params   Array temporary storage for the name/value of current field
689              */
690             var this_field_params = {};
692             if($this_field.is('.transformed')) {
693                 transformation_fields =  true;
694             }
695             /**
696              * @var is_null String capturing whether 'checkbox_null_<field_name>_<row_index>' is checked.
697              */
698             var is_null = $this_field.find('input:checkbox').is(':checked');
699             var value;
701             if (is_null) {
702                 sql_query += ' ' + field_name + "=NULL , ";
703             } else {
704                 if($this_field.is(":not(.relation, .enum)")) {
705                     this_field_params[field_name] = $this_field.find('textarea').val();
706                     if($this_field.is('.transformed')) {
707                         $.extend(transform_fields, this_field_params);
708                     }
709                 }
710                 else {
711                     // results from a drop-down
712                     $test_element = $this_field.find('select');
713                     if ($test_element.length != 0) {
714                         this_field_params[field_name] = $test_element.val();
715                     }
717                     // results from Browse foreign value
718                     $test_element = $this_field.find('span.curr_value');
719                     if ($test_element.length != 0) {
720                         this_field_params[field_name] = $test_element.text();
721                     }
723                     if($this_field.is('.relation')) {
724                         $.extend(relation_fields, this_field_params);
725                     }
726                 }
728                 sql_query += ' ' + field_name + "='" + this_field_params[field_name].replace(/'/g, "''") + "' , ";
729             }
730         })
732         //Remove the last ',' appended in the above loop
733         sql_query = sql_query.replace(/,\s$/, '');
734         sql_query += ' WHERE ' + PMA_urldecode(where_clause);
736         /**
737          * @var rel_fields_list  String, url encoded representation of {@link relations_fields}
738          */
739         var rel_fields_list = $.param(relation_fields);
741         /**
742          * @var transform_fields_list  String, url encoded representation of {@link transform_fields}
743          */
744         var transform_fields_list = $.param(transform_fields);
746         // Make the Ajax post after setting all parameters
747         /**
748          * @var post_params Object containing parameters for the POST request
749          */
750         var post_params = {'ajax_request' : true,
751                             'sql_query' : sql_query,
752                             'disp_direction' : disp_mode,
753                             'token' : window.parent.token,
754                             'db' : window.parent.db,
755                             'table' : window.parent.table,
756                             'clause_is_unique' : nonunique,
757                             'where_clause' : where_clause,
758                             'rel_fields_list' : rel_fields_list,
759                             'do_transformations' : transformation_fields,
760                             'transform_fields_list' : transform_fields_list,
761                             'goto' : 'sql.php',
762                             'submit_type' : 'save'
763                           };
765         $.post('tbl_replace.php', post_params, function(data) {
766             if(data.success == true) {
767                 PMA_ajaxShowMessage(data.message);
768                 $this_td.removeClass('inline_edit_active').addClass('inline_edit_anchor');
770                 $input_siblings.each(function() {
771                     // Inline edit post has been successful.
772                     $this_sibling = $(this);
774                     var is_null = $this_sibling.find('input:checkbox').is(':checked');
775                     if (is_null) {
776                         $this_sibling.html('NULL');
777                         $this_sibling.addClass('null');
778                     } else {
779                         $this_sibling.removeClass('null');
780                         if($this_sibling.is(':not(.relation, .enum)')) {
781                             /**
782                              * @var new_html    String containing value of the data field after edit
783                              */
784                             var new_html = $this_sibling.find('textarea').val();
786                             if($this_sibling.is('.transformed')) {
787                                 var field_name = getFieldName($this_sibling, disp_mode);
788                                 $.each(data.transformations, function(key, value) {
789                                     if(key == field_name) {
790                                         if($this_sibling.is('.text_plain, .application_octetstream')) {
791                                             new_html = value;
792                                             return false;
793                                         }
794                                         else {
795                                             var new_value = $this_sibling.find('textarea').val();
796                                             new_html = $(value).append(new_value);
797                                             return false;
798                                         }
799                                     }
800                                 })
801                             }
802                         }
803                         else {
804                             var new_html = '';
805                             var new_value = '';
806                             $test_element = $this_sibling.find('select');
807                             if ($test_element.length != 0) {
808                                 new_value = $test_element.val();
809                             }
811                             $test_element = $this_sibling.find('span.curr_value');
812                             if ($test_element.length != 0) {
813                                 new_value = $test_element.text();
814                             }
816                             if($this_sibling.is('.relation')) {
817                                 var field_name = getFieldName($this_sibling, disp_mode);
818                                 $.each(data.relations, function(key, value) {
819                                     if(key == field_name) {
820                                         new_html = $(value).append(new_value);
821                                         return false;
822                                     }
823                                 })
824                             }
825                             if($this_sibling.is('.enum')) {
826                                 new_html = new_value;
827                             }
828                         }
829                         $this_sibling.html(new_html);
830                     }
831                 })
832             }
833             else {
834                 PMA_ajaxShowMessage(data.error);
835             };
836         }) // end $.post()
837     }) // End After editing, clicking again should post data
838 }, 'top.frame_content') // end $(document).ready()
841  * Starting from some th, change the class of all td under it
842  */
843 function PMA_changeClassForColumn($this_th, newclass) {
844     // index 0 is the th containing the big T
845     var th_index = $this_th.index();
846     // .eq() is zero-based
847     th_index--;
848     var $tr_with_data = $this_th.closest('table').find('tbody tr ').has('td.data');
849     $tr_with_data.each(function() {
850         $(this).find('td.data:eq('+th_index+')').toggleClass(newclass);
851     });
854 $(document).ready(function() {
856     $('.browse_foreign').live('click', function(e) {
857         e.preventDefault();
858         window.open(this.href, 'foreigners', 'width=640,height=240,scrollbars=yes,resizable=yes');
859         $anchor = $(this);
860         $anchor.addClass('browse_foreign_clicked');
861         return false;
862     });
864     /**
865      * vertical column highlighting in horizontal mode when hovering over the column header
866      */
867     $('.column_heading').live('hover', function() {
868         PMA_changeClassForColumn($(this), 'hover');
869         });
871     /**
872      * vertical column marking in horizontal mode when clicking the column header
873      */
874     $('.column_heading').live('click', function() {
875         PMA_changeClassForColumn($(this), 'marked');
876         });
879 /**#@- */