Translation update done using Pootle.
[phpmyadmin-themes.git] / js / sql.js
blob80f43375be2ac5b0298121067bed0f461ddff98e
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         // 4 columns to account for the checkbox, edit, delete and appended inline edit anchors but index is zero-based so substract 3
41         var field_name = $('#table_results').find('thead').find('th:nth('+ (this_field_index-3 )+') 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-3 )+')').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             var img_src = $img_object.attr('src').replace(/b_edit/,'b_inline_edit');
73             $img_object.attr('src', img_src);
75             $cloned_tr.find('td')
76              .addClass('inline_edit_anchor')
77              .find('a').attr('href', '#')
78              .find('span')
79              .text(' ' + PMA_messages['strInlineEdit'])
80              .prepend($img_object);
82             $cloned_tr.insertAfter($this_tr);
83         });
85         $("#table_results").find('tr').find(':checkbox').closest('tr').find('th')
86          .attr('rowspan', '4');
87     }
88     else {
89         $('.edit_row_anchor').each(function() {
91             $this_td = $(this)
92             $this_td.removeClass('edit_row_anchor');
94             var $cloned_anchor = $this_td.clone();
96             var $img_object = $cloned_anchor.find('img').attr('title', PMA_messages['strInlineEdit']);
97             var img_src = $img_object.attr('src').replace(/b_edit/,'b_inline_edit');
98             $img_object.attr('src', img_src);
100             $cloned_anchor.addClass('inline_edit_anchor')
101             .find('a').attr('href', '#')
102             .find('span')
103             .text(' ' + PMA_messages['strInlineEdit'])
104             .prepend($img_object);
106             $this_td.after($cloned_anchor);
107         });
109         $('#rowsDeleteForm').find('thead, tbody').find('th').each(function() {
110             var $this_th = $(this);
111             if ($this_th.attr('colspan') == 4) {
112                 $this_th.attr('colspan', '5')
113             }
114         });
115     }
118 /**#@+
119  * @namespace   jQuery
120  */
123  * @description <p>Ajax scripts for sql and browse pages</p>
125  * Actions ajaxified here:
126  * <ul>
127  * <li>Retrieve results of an SQL query</li>
128  * <li>Paginate the results table</li>
129  * <li>Sort the results table</li>
130  * <li>Change table according to display options</li>
131  * <li>Inline editing of data</li>
132  * </ul>
134  * @name        document.ready
135  * @memberOf    jQuery
136  */
137 $(document).ready(function() {
139     /**
140      * Set a parameter for all Ajax queries made on this page.  Don't let the
141      * web server serve cached pages
142      */
143     $.ajaxSetup({
144         cache: 'false'
145     });
147     /**
148      * current value of the direction in which the table is displayed
149      * @type    String
150      * @fieldOf jQuery
151      * @name    disp_mode
152      */
153     var disp_mode = $("#top_direction_dropdown").val();
155     /**
156      * Update value of {@link jQuery.disp_mode} everytime the direction dropdown changes value
157      * @memberOf    jQuery
158      * @name        direction_dropdown_change
159      */
160     $("#top_direction_dropdown, #bottom_direction_dropdown").live('change', function(event) {
161         disp_mode = $(this).val();
162     })
164     /**
165      * Attach the {@link appendInlineAnchor} function to a custom event, which
166      * will be triggered manually everytime the table of results is reloaded
167      * @memberOf    jQuery
168      */
169     $("#sqlqueryresults").live('appendAnchor',function() {
170         appendInlineAnchor();
171     })
173     /**
174      * Trigger the appendAnchor event to prepare the first table for inline edit
175      * (see $GLOBALS['cfg']['AjaxEnable'])
176      * @memberOf    jQuery
177      * @name        sqlqueryresults_trigger
178      */
179     $("#sqlqueryresults.ajax").trigger('appendAnchor');
181     /**
182      * Append the "Show/Hide query box" message to the query input form
183      *
184      * @memberOf jQuery
185      * @name    appendToggleSpan
186      */
187     // do not add this link more than once
188     if (! $('#sqlqueryform').find('a').is('#togglequerybox')) {
189         $('<a id="togglequerybox"></a>')
190         .html(PMA_messages['strHideQueryBox'])
191         .appendTo("#sqlqueryform");
193         // Attach the toggling of the query box visibility to a click
194         $("#togglequerybox").bind('click', function() {
195             var $link = $(this)
196             $link.siblings().slideToggle("medium");
197             if ($link.text() == PMA_messages['strHideQueryBox']) {
198                 $link.text(PMA_messages['strShowQueryBox']);
199             } else {
200                 $link.text(PMA_messages['strHideQueryBox']);
201             }
202             // avoid default click action
203             return false;
204         })
205     }
207     /**
208      * Ajax Event handler for 'SQL Query Submit'
209      *
210      * @see         PMA_ajaxShowMessage()
211      * @see         $cfg['AjaxEnable']
212      * @memberOf    jQuery
213      * @name        sqlqueryform_submit
214      */
215     $("#sqlqueryform.ajax").live('submit', function(event) {
216         event.preventDefault();
217         // remove any div containing a previous error message
218         $('.error').remove();
220         $form = $(this);
221         PMA_ajaxShowMessage();
223             if (! $form.find('input:hidden').is('#ajax_request_hidden')) {
224                 $form.append('<input type="hidden" id="ajax_request_hidden" name="ajax_request" value="true" />');
225             }
227         $.post($(this).attr('action'), $(this).serialize() , function(data) {
228             if(data.success == true) {
229                 // fade out previous success message, if any
230                 $('.success').fadeOut();
231                 // show a message that stays on screen
232                 $('#sqlqueryform').before(data.message);
233                 $('#sqlqueryresults').show();
234                 // this happens if a USE command was typed
235                 if (typeof data.reload != 'undefined') {
236                     $form.find('input[name=db]').val(data.db);
237                     // need to regenerate the whole upper part
238                     $form.find('input[name=ajax_request]').remove();
239                     $form.append('<input type="hidden" name="reload" value="true" />');
240                     $.post('db_sql.php', $form.serialize(), function(data) {
241                         $('body').html(data);
242                     }); // end inner post
243                 }
244             }
245             else if (data.success == false ) {
246                 // show an error message that stays on screen
247                 $('#sqlqueryform').before(data.error);
248                 $('#sqlqueryresults').hide();
249             }
250             else {
251                 // real results are returned
252                 $('#sqlqueryresults').show();
253                 $("#sqlqueryresults").html(data);
254                 $("#sqlqueryresults").trigger('appendAnchor');
255                 if($("#togglequerybox").siblings(":visible").length > 0) {
256                     $("#togglequerybox").trigger('click');
257                 }
258                 PMA_init_slider();
259             }
260         }) // end $.post()
261     }) // end SQL Query submit
263     /**
264      * Ajax Event handlers for Paginating the results table
265      */
267     /**
268      * Paginate when we click any of the navigation buttons
269      * (only if the element has the ajax class, see $cfg['AjaxEnable'])
270      * @memberOf    jQuery
271      * @name        paginate_nav_button_click
272      * @uses        PMA_ajaxShowMessage()
273      * @see         $cfg['AjaxEnable']
274      */
275     $("input[name=navig].ajax").live('click', function(event) {
276         /** @lends jQuery */
277         event.preventDefault();
279         PMA_ajaxShowMessage();
281         /**
282          * @var $the_form    Object referring to the form element that paginates the results table
283          */
284         var $the_form = $(this).parent("form");
286         $the_form.append('<input type="hidden" name="ajax_request" value="true" />');
288         $.post($the_form.attr('action'), $the_form.serialize(), function(data) {
289             $("#sqlqueryresults").html(data);
290             $("#sqlqueryresults").trigger('appendAnchor');
291             PMA_init_slider();
292         }) // end $.post()
293     })// end Paginate results table
295     /**
296      * Paginate results with Page Selector dropdown
297      * @memberOf    jQuery
298      * @name        paginate_dropdown_change
299      * @see         $cfg['AjaxEnable']
300      */
301     $("#pageselector").live('change', function(event) {
302         var $the_form = $(this).parent("form");
304         if ($(this).hasClass('ajax')) {
305             event.preventDefault();
307             PMA_ajaxShowMessage();
309             $.post($the_form.attr('action'), $the_form.serialize() + '&ajax_request=true', function(data) {
310                 $("#sqlqueryresults").html(data);
311                 $("#sqlqueryresults").trigger('appendAnchor');
312                 PMA_init_slider();
313             }) // end $.post()
314         } else {
315             $the_form.submit();
316         }
318     })// end Paginate results with Page Selector
320     /**
321      * Ajax Event handler for sorting the results table
322      * @memberOf    jQuery
323      * @name        table_results_sort_click
324      * @see         $cfg['AjaxEnable']
325      */
326     $("#table_results.ajax").find("a[title=Sort]").live('click', function(event) {
327         event.preventDefault();
329         PMA_ajaxShowMessage();
331         $anchor = $(this);
333         $.get($anchor.attr('href'), $anchor.serialize() + '&ajax_request=true', function(data) {
334             $("#sqlqueryresults")
335              .html(data)
336              .trigger('appendAnchor');
337         }) // end $.get()
338     })//end Sort results table
340     /**
341      * Ajax Event handler for the display options
342      * @memberOf    jQuery
343      * @name        displayOptionsForm_submit
344      * @see         $cfg['AjaxEnable']
345      */
346     $("#displayOptionsForm.ajax").live('submit', function(event) {
347         event.preventDefault();
349         $form = $(this);
351         $.post($form.attr('action'), $form.serialize() + '&ajax_request=true' , function(data) {
352             $("#sqlqueryresults")
353              .html(data)
354              .trigger('appendAnchor');
355             PMA_init_slider();
356         }) // end $.post()
357     })
358     //end displayOptionsForm handler
360     /**
361      * Ajax Event handlers for Inline Editing
362      */
364     /**
365      * On click, replace the fields of current row with an input/textarea
366      * @memberOf    jQuery
367      * @name        inline_edit_start
368      * @see         PMA_ajaxShowMessage()
369      * @see         getFieldName()
370      */
371     $(".inline_edit_anchor").live('click', function(event) {
372         /** @lends jQuery */
373         event.preventDefault();
375         $(this).removeClass('inline_edit_anchor').addClass('inline_edit_active');
377         // Initialize some variables
378         if(disp_mode == 'vertical') {
379             /**
380              * @var this_row_index  Index of the current <td> in the parent <tr>
381              *                      Current <td> is the inline edit anchor.
382              */
383             var this_row_index = $(this).index();
384             /**
385              * @var $input_siblings  Object referring to all inline editable events from same row
386              */
387             var $input_siblings = $(this).parents('tbody').find('tr').find('.inline_edit:nth('+this_row_index+')');
388             /**
389              * @var where_clause    String containing the WHERE clause to select this row
390              */
391             var where_clause = $(this).parents('tbody').find('tr').find('.where_clause:nth('+this_row_index+')').val();
392         }
393         else {
394             var $input_siblings = $(this).parent('tr').find('.inline_edit');
395             var where_clause = $(this).parent('tr').find('.where_clause').val();
396         }
398         $input_siblings.each(function() {
399             /** @lends jQuery */
400             /**
401              * @var data_value  Current value of this field
402              */
403             var data_value = $(this).html();
405             // We need to retrieve the value from the server for truncated/relation fields
406             // Find the field name
408             /**
409              * @var this_field  Object referring to this field (<td>)
410              */
411             var $this_field = $(this);
412             /**
413              * @var field_name  String containing the name of this field.
414              * @see getFieldName()
415              */
416             var field_name = getFieldName($this_field, disp_mode);
418             // In each input sibling, wrap the current value in a textarea
419             // and store the current value in a hidden span
420             if($this_field.is(':not(.truncated, .transformed, .relation, .enum, .null)')) {
421                 // handle non-truncated, non-transformed, non-relation values
422                 // We don't need to get any more data, just wrap the value
423                 $this_field.html('<textarea>'+data_value+'</textarea>')
424                 .append('<span class="original_data">'+data_value+'</span>');
425                 $(".original_data").hide();
426             }
427             else if($this_field.is('.truncated, .transformed')) {
428                 /** @lends jQuery */
429                 //handle truncated/transformed values values
431                 /**
432                  * @var sql_query   String containing the SQL query used to retrieve value of truncated/transformed data
433                  */
434                 var sql_query = 'SELECT ' + field_name + ' FROM ' + window.parent.table + ' WHERE ' + where_clause;
436                 // Make the Ajax call and get the data, wrap it and insert it
437                 $.post('sql.php', {
438                     'token' : window.parent.token,
439                     'db' : window.parent.db,
440                     'ajax_request' : true,
441                     'sql_query' : sql_query,
442                     'inline_edit' : true
443                 }, function(data) {
444                     if(data.success == true) {
445                         $this_field.html('<textarea>'+data.value+'</textarea>')
446                         .append('<span class="original_data">'+data_value+'</span>');
447                         $(".original_data").hide();
448                     }
449                     else {
450                         PMA_ajaxShowMessage(data.error);
451                     }
452                 }) // end $.post()
453             }
454             else if($this_field.is('.relation')) {
455                 /** @lends jQuery */
456                 //handle relations
458                 /**
459                  * @var curr_value  String containing the current value of this relational field
460                  */
461                 var curr_value = $this_field.find('a').text();
463                 /**
464                  * @var post_params Object containing parameters for the POST request
465                  */
466                 var post_params = {
467                         'ajax_request' : true,
468                         'get_relational_values' : true,
469                         'db' : window.parent.db,
470                         'table' : window.parent.table,
471                         'column' : field_name,
472                         'token' : window.parent.token,
473                         'curr_value' : curr_value
474                 }
476                 $.post('sql.php', post_params, function(data) {
477                     $this_field.html(data.dropdown)
478                     .append('<span class="original_data">'+data_value+'</span>');
479                     $(".original_data").hide();
480                 }) // end $.post()
481             }
482             else if($this_field.is('.enum')) {
483                 /** @lends jQuery */
484                 //handle enum fields
485                 /**
486                  * @var curr_value  String containing the current value of this relational field
487                  */
488                 var curr_value = $this_field.text();
490                 /**
491                  * @var post_params Object containing parameters for the POST request
492                  */
493                 var post_params = {
494                         'ajax_request' : true,
495                         'get_enum_values' : true,
496                         'db' : window.parent.db,
497                         'table' : window.parent.table,
498                         'column' : field_name,
499                         'token' : window.parent.token,
500                         'curr_value' : curr_value
501                 }
503                 $.post('sql.php', post_params, function(data) {
504                     $this_field.html(data.dropdown)
505                     .append('<span class="original_data">'+data_value+'</span>');
506                     $(".original_data").hide();
507                 }) // end $.post()
508             }
509             else if($this_field.is('.null')) {
510                 //handle null fields
511                 $this_field.html('<textarea></textarea>')
512                 .append('<span class="original_data">NULL</span>');
513                 $(".original_data").hide();
514             }
515         })
516     }) // End On click, replace the current field with an input/textarea
518     /**
519      * After editing, clicking again should post data
520      *
521      * @memberOf    jQuery
522      * @name        inline_edit_save
523      * @see         PMA_ajaxShowMessage()
524      * @see         getFieldName()
525      */
526     $(".inline_edit_active").live('click', function(event) {
527         /** @lends jQuery */
528         event.preventDefault();
530         /**
531          * @var $this_td    Object referring to the td containing the
532          * "Inline Edit" link that was clicked to save the row that is
533          * being edited
534          *
535          */
536         var $this_td = $(this);
538         var $test_element = ''; // to test the presence of a element
540         // Initialize variables
541         if(disp_mode == 'vertical') {
542             /**
543              * @var this_td_index  Index of the current <td> in the parent <tr>
544              *                      Current <td> is the inline edit anchor.
545              */
546             var this_td_index = $this_td.index();
547             /**
548              * @var $input_siblings  Object referring to all inline editable events from same row
549              */
550             var $input_siblings = $this_td.parents('tbody').find('tr').find('.inline_edit:nth('+this_td_index+')');
551             /**
552              * @var where_clause    String containing the WHERE clause to select this row
553              */
554             var where_clause = $this_td.parents('tbody').find('tr').find('.where_clause:nth('+this_td_index+')').val();
555         }
556         else {
557             var $input_siblings = $this_td.parent('tr').find('.inline_edit');
558             var where_clause = $this_td.parent('tr').find('.where_clause').val();
559         }
561         /**
562          * @var nonunique   Boolean, whether this row is unique or not
563          */
564         if($this_td.is('.nonunique')) {
565             var nonunique = 0;
566         }
567         else {
568             var nonunique = 1;
569         }
571         // Collect values of all fields to submit, we don't know which changed
572         /**
573          * @var params_to_submit    Array containing the name/value pairs of all fields
574          */
575         var params_to_submit = {};
576         /**
577          * @var relation_fields Array containing the name/value pairs of relational fields
578          */
579         var relation_fields = {};
580         /**
581          * @var transform_fields    Array containing the name/value pairs for transformed fields
582          */
583         var transform_fields = {};
584         /**
585          * @var transformation_fields   Boolean, if there are any transformed fields in this row
586          */
587         var transformation_fields = false;
589         $input_siblings.each(function() {
590             /** @lends jQuery */
591             /**
592              * @var this_field  Object referring to this field (<td>)
593              */
594             var $this_field = $(this);
595             /**
596              * @var field_name  String containing the name of this field.
597              * @see getFieldName()
598              */
599             var field_name = getFieldName($this_field, disp_mode);
601             /**
602              * @var this_field_params   Array temporary storage for the name/value of current field
603              */
604             var this_field_params = {};
606             if($this_field.is('.transformed')) {
607                 transformation_fields =  true;
608             }
610             if($this_field.is(":not(.relation, .enum)")) {
611                 this_field_params[field_name] = $this_field.find('textarea').val();
612                 if($this_field.is('.transformed')) {
613                     $.extend(transform_fields, this_field_params);
614                 }
615             }
616             else {
617                 // results from a drop-down
618                 $test_element = $this_field.find('select');
619                 if ($test_element.length != 0) {
620                     this_field_params[field_name] = $test_element.val();
621                 }
623                 // results from Browse foreign value
624                 $test_element = $this_field.find('span.curr_value');
625                 if ($test_element.length != 0) {
626                     this_field_params[field_name] = $test_element.text();
627                 }
629                 if($this_field.is('.relation')) {
630                     $.extend(relation_fields, this_field_params);
631                 }
632             }
634             $.extend(params_to_submit, this_field_params);
635         })
637         /**
638          * @var sql_query   String containing the SQL query to update this row
639          */
640         var sql_query = 'UPDATE ' + window.parent.table + ' SET ';
642         $.each(params_to_submit, function(key, value) {
643             if(value.length == 0) {
644                 value = 'NULL'
645             }
646            sql_query += ' ' + key + "='" + value.replace(/'/g, "''") + "' , ";
647         })
648         //Remove the last ',' appended in the above loop
649         sql_query = sql_query.replace(/,\s$/, '');
650         sql_query += ' WHERE ' + PMA_urldecode(where_clause);
652         /**
653          * @var rel_fields_list  String, url encoded representation of {@link relations_fields}
654          */
655         var rel_fields_list = $.param(relation_fields);
657         /**
658          * @var transform_fields_list  String, url encoded representation of {@link transform_fields}
659          */
660         var transform_fields_list = $.param(transform_fields);
662         // Make the Ajax post after setting all parameters
663         /**
664          * @var post_params Object containing parameters for the POST request
665          */
666         var post_params = {'ajax_request' : true,
667                             'sql_query' : sql_query,
668                             'disp_direction' : disp_mode,
669                             'token' : window.parent.token,
670                             'db' : window.parent.db,
671                             'table' : window.parent.table,
672                             'clause_is_unique' : nonunique,
673                             'where_clause' : where_clause,
674                             'rel_fields_list' : rel_fields_list,
675                             'do_transformations' : transformation_fields,
676                             'transform_fields_list' : transform_fields_list,
677                             'goto' : 'sql.php',
678                             'submit_type' : 'save'
679                           };
681         $.post('tbl_replace.php', post_params, function(data) {
682             if(data.success == true) {
683                 PMA_ajaxShowMessage(data.message);
684                 $this_td.removeClass('inline_edit_active').addClass('inline_edit_anchor');
686                 $input_siblings.each(function() {
687                     // Inline edit post has been successful.
688                     $this_sibling = $(this);
689                     if($this_sibling.is(':not(.relation, .enum)')) {
690                         /**
691                          * @var new_html    String containing value of the data field after edit
692                          */
693                         var new_html = $this_sibling.find('textarea').val();
695                         if($this_sibling.is('.transformed')) {
696                             var field_name = getFieldName($this_sibling, disp_mode);
697                             $.each(data.transformations, function(key, value) {
698                                 if(key == field_name) {
699                                     if($this_sibling.is('.text_plain, .application_octetstream')) {
700                                         new_html = value;
701                                         return false;
702                                     }
703                                     else {
704                                         var new_value = $this_sibling.find('textarea').val();
705                                         new_html = $(value).append(new_value);
706                                         return false;
707                                     }
708                                 }
709                             })
710                         }
711                     }
712                     else {
713                         var new_html = '';
714                         var new_value = '';
715                         $test_element = $this_sibling.find('select');
716                         if ($test_element.length != 0) {
717                             new_value = $test_element.val();
718                         }
720                         $test_element = $this_sibling.find('span.curr_value');
721                         if ($test_element.length != 0) {
722                             new_value = $test_element.text();
723                         }
726                         if($this_sibling.is('.relation')) {
727                             var field_name = getFieldName($this_sibling, disp_mode);
728                             $.each(data.relations, function(key, value) {
729                                 if(key == field_name) {
730                                     new_html = $(value).append(new_value);
731                                     return false;
732                                 }
733                             })
734                         }
735                         if($this_sibling.is('.enum')) {
736                             new_html = new_value;
737                         }
738                     }
739                     $this_sibling.html(new_html);
740                 })
741             }
742             else {
743                 PMA_ajaxShowMessage(data.error);
744             };
745         }) // end $.post()
746     }) // End After editing, clicking again should post data
747 }, 'top.frame_content') // end $(document).ready()
750  * Starting from some th, change the class of all td under it
751  */
752 function PMA_changeClassForColumn($this_th, newclass) {
753     // index 0 is the th containing the big T
754     var th_index = $this_th.index();
755     // .eq() is zero-based
756     th_index--;
757     var $tr_with_data = $this_th.closest('table').find('tbody tr ').has('td.data');
758     $tr_with_data.each(function() {
759         $(this).find('td.data:eq('+th_index+')').toggleClass(newclass);
760     });
763 $(document).ready(function() {
765     $('.browse_foreign').live('click', function(e) {
766         e.preventDefault();
767         window.open(this.href, 'foreigners', 'width=640,height=240,scrollbars=yes,resizable=yes');
768         $anchor = $(this);
769         $anchor.addClass('browse_foreign_clicked');
770         return false;
771     });
773     /**
774      * vertical column highlighting in horizontal mode when hovering over the column header
775      */
776     $('.column_heading').live('hover', function() {
777         PMA_changeClassForColumn($(this), 'hover');
778         });
780     /**
781      * vertical column marking in horizontal mode when clicking the column header
782      */
783     $('.column_heading').live('click', function() {
784         PMA_changeClassForColumn($(this), 'marked');
785         });
788 /**#@- */