Translation update done using Pootle.
[phpmyadmin-themes.git] / js / sql.js
bloba2000ac2440983908c18cfdaebd91ee6a2685aed
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  * @version $Id$
9  */
11 /**
12  * Get the field name for the current field.  Required to construct the query
13  * for inline editing
14  *
15  * @param   this_field_obj  jQuery object that points to the current field's tr
16  * @param   disp_mode       string
17  */
18 function getFieldName(this_field_obj, disp_mode) {
20     if(disp_mode == 'vertical') {
21         var field_name = $(this_field_obj).siblings('th').find('a').text();
22     }
23     else {
24         var this_field_index = $(this_field_obj).index();
25         if(window.parent.text_dir == 'ltr') {
26             // 4 columns to account for the checkbox, edit, delete and appended inline edit anchors
27             var field_name = $(this_field_obj).parents('table').find('thead').find('th:nth('+ (this_field_index-4 )+') a').text();
28         }
29         else {
30             var field_name = $(this_field_obj).parents('table').find('thead').find('th:nth('+ this_field_index+') a').text();
31         }
32     }
34     field_name = $.trim(field_name);
36     return field_name;
39 /**
40  * The function that iterates over each row in the table_results and appends a
41  * new inline edit anchor to each table row.
42  *
43  * @param   disp_mode   string
44  */
45 function appendInlineAnchor(disp_mode) {
46     if(disp_mode == 'vertical') {
47         var cloned_row = $('.edit_row_anchor').removeClass('edit_row_anchor').parent('tr').clone();
49         var img_object = $(cloned_row).find('img:first').attr('title', PMA_messages['strInlineEdit']);
51         $(cloned_row).find('td').addClass('edit_row_anchor')
52         .find('a').attr('href', '#')
53         .find('div')
54         .text(PMA_messages['strInlineEdit'])
55         .prepend(img_object);
57         $(cloned_row).insertBefore($('.where_clause').parent('tr'));
59         $("#table_results").find('tr:first').find('th')
60         .attr('rowspan', '4');
61     }
62     else {
63         $('.edit_row_anchor').each(function() {
65             $(this).removeClass('edit_row_anchor');
67             var cloned_anchor = $(this).clone();
69             var img_object = $(cloned_anchor).find('img').attr('title', PMA_messages['strInlineEdit']);
71             $(cloned_anchor).addClass('edit_row_anchor')
72             .find('a').attr('href', '#')
73             .find('div')
74             .text(PMA_messages['strInlineEdit'])
75             .prepend(img_object);
77             $(this).siblings('.where_clause')
78             .before(cloned_anchor);
79         });
81         $('#rowsDeleteForm').find('thead').find('th').each(function() {
82             if($(this).attr('colspan') == 3) {
83                 $(this).attr('colspan', '4')
84             }
85         })
86     }
89 /**#@+
90  * @namespace   jQuery
91  */
93 /**
94  * @description <p>Ajax scripts for sql and browse pages</p>
95  *
96  * Actions ajaxified here:
97  * <ul>
98  * <li>Retrieve results of an SQL query</li>
99  * <li>Paginate the results table</li>
100  * <li>Sort the results table</li>
101  * <li>Change table according to display options</li>
102  * <li>Inline editing of data</li>
103  * </ul>
105  * @name        document.ready
106  * @memberOf    jQuery
107  */
108 $(document).ready(function() {
111     /**
112      * current value of the direction in which the table is displayed
113      * @type    String
114      * @fieldOf jQuery
115      * @name    disp_mode
116      */
117     var disp_mode = $("#top_direction_dropdown").val();
119     /**
120      * Update value of {@link jQuery.disp_mode} everytime the direction dropdown changes value
121      * @memberOf    jQuery
122      * @name        direction_dropdown_change
123      */
124     $("#top_direction_dropdown, #bottom_direction_dropdown").live('change', function(event) {
125         disp_mode = $(this).val();
126     })
128     /**
129      * Attach the {@link appendInlineAnchor} function to a custom event, which
130      * will be triggered manually everytime the table of results is reloaded
131      * @memberOf    jQuery
132      * @name        sqlqueryresults_live
133      */
134     $("#sqlqueryresults").live('appendAnchor',function() {
135         appendInlineAnchor(disp_mode);
136     })
138     /**
139      * Trigger the appendAnchor event to prepare the first table for inline edit
140      *
141      * @memberOf    jQuery
142      * @name        sqlqueryresults_trigger
143      */
144     $("#sqlqueryresults").trigger('appendAnchor');
146     /**
147      * Append the Toggle Query Box message to the query input form
148      *
149      * @memberOf jQuery
150      * @name    appendToggleSpan
151      */
152     $('<span id="togglequerybox"></span>')
153     .html(PMA_messages['strToggleQueryBox'])
154     .appendTo("#sqlqueryform");
156     // Attach the toggling of the query box visibility to a click
157     $("#togglequerybox").live('click', function() {
158         $(this).siblings().slideToggle("medium");
159     })
160     
161     /**
162      * Ajax Event handler for 'SQL Query Submit'
163      *
164      * @see         PMA_ajaxShowMessage()
165      * @memberOf    jQuery
166      * @name        sqlqueryform_submit
167      */
168     $("#sqlqueryform").live('submit', function(event) {
169         event.preventDefault();
171         PMA_ajaxShowMessage();
173         $(this).append('<input type="hidden" name="ajax_request" value="true" />');
175         $.post($(this).attr('action'), $(this).serialize() , function(data) {
176             if(data.success == true) {
177                 PMA_ajaxShowMessage(data.message);
178             }
179             else if (data.success == false ) {
180                 PMA_ajaxShowMessage(data.error);
181             }
182             else {
183                 $("#sqlqueryresults").html(data);
184                 $("#sqlqueryresults").trigger('appendAnchor');
185                 if($("#togglequerybox").siblings(":visible").length > 0) {
186                     $("#togglequerybox").trigger('click');
187                 }
188             }
189         }) // end $.post()
190     }) // end SQL Query submit
192     /**
193      * Ajax Event handlers for Paginating the results table
194      */
196     /**
197      * Paginate when we click any of the navigation buttons
198      * @memberOf    jQuery
199      * @name        paginate_nav_button_click
200      * @uses        PMA_ajaxShowMessage()
201      */
202     $("input[name=navig]").live('click', function(event) {
203         /** @lends jQuery */
204         event.preventDefault();
206         PMA_ajaxShowMessage();
207         
208         /**
209          * @var the_form    Object referring to the form element that paginates the results table
210          */
211         var the_form = $(this).parent("form");
213         $(the_form).append('<input type="hidden" name="ajax_request" value="true" />');
215         $.post($(the_form).attr('action'), $(the_form).serialize(), function(data) {
216             $("#sqlqueryresults").html(data);
217             $("#sqlqueryresults").trigger('appendAnchor');
218         }) // end $.post()
219     })// end Paginate results table
221     /**
222      * Paginate results with Page Selector dropdown
223      * @memberOf    jQuery
224      * @name        paginate_dropdown_change
225      */
226     $("#pageselector").live('change', function(event) {
227         event.preventDefault();
229         PMA_ajaxShowMessage();
231         $.get($(this).attr('href'), $(this).serialize() + '&ajax_request=true', function(data) {
232             $("#sqlqueryresults").html(data);
233             $("#sqlqueryresults").trigger('appendAnchor');
234         }) // end $.get()
235     })// end Paginate results with Page Selector
237     /**
238      * Ajax Event handler for sorting the results table
239      * @memberOf    jQuery
240      * @name        table_results_sort_click
241      */
242     $("#table_results").find("a[title=Sort]").live('click', function(event) {
243         event.preventDefault();
245         PMA_ajaxShowMessage();
247         $.get($(this).attr('href'), $(this).serialize() + '&ajax_request=true', function(data) {
248             $("#sqlqueryresults").html(data);
249             $("#sqlqueryresults").trigger('appendAnchor');
250         }) // end $.get()
251     })//end Sort results table
253     /**
254      * Ajax Event handler for the display options
255      * @memberOf    jQuery
256      * @name        displayOptionsForm_submit
257      */
258     $("#displayOptionsForm").live('submit', function(event) {
259         event.preventDefault();
261         $.post($(this).attr('action'), $(this).serialize() + '&ajax_request=true' , function(data) {
262             $("#sqlqueryresults").html(data);
263             $("#sqlqueryresults").trigger('appendAnchor');
264         }) // end $.post()
265     })
266     //end displayOptionsForm handler
268     /**
269      * Ajax Event handlers for Inline Editing
270      */
272     /**
273      * On click, replace the current field with an input/textarea
274      * @memberOf    jQuery
275      * @name        inline_edit_start
276      * @see         PMA_ajaxShowMessage()
277      * @see         getFieldName()
278      */
279     $(".edit_row_anchor").live('click', function(event) {
280         /** @lends jQuery */
281         event.preventDefault();
283         $(this).removeClass('edit_row_anchor').addClass('edit_row_anchor_active');
285         // Initialize some variables
286         if(disp_mode == 'vertical') {
287             /**
288              * @var this_row_index  Index of the current <td> in the parent <tr>
289              *                      Current <td> is the inline edit anchor.
290              */
291             var this_row_index = $(this).index();
292             /**
293              * @var input_siblings  Object referring to all inline editable events from same row
294              */
295             var input_siblings = $(this).parents('tbody').find('tr').find('.data_inline_edit:nth('+this_row_index+')');
296             /**
297              * @var where_clause    String containing the WHERE clause to select this row
298              */
299             var where_clause = $(this).parents('tbody').find('tr').find('.where_clause:nth('+this_row_index+')').val();
300         }
301         else {
302             var input_siblings = $(this).parent('tr').find('.data_inline_edit');
303             var where_clause = $(this).parent('tr').find('.where_clause').val();
304         }
306         $(input_siblings).each(function() {
307             /** @lends jQuery */
308             /**
309              * @var data_value  Current value of this field
310              */
311             var data_value = $(this).html();
313             // We need to retrieve the value from the server for truncated/relation fields
314             // Find the field name
315             
316             /**
317              * @var this_field  Object referring to this field (<td>)
318              */
319             var this_field = $(this);
320             /**
321              * @var field_name  String containing the name of this field.
322              * @see getFieldName()
323              */
324             var field_name = getFieldName($(this), disp_mode);
326             // In each input sibling, wrap the current value in a textarea
327             // and store the current value in a hidden span
328             if($(this).is(':not(.truncated, .transformed, .relation, .enum, .null)')) {
329                 // handle non-truncated, non-transformed, non-relation values
330                 // We don't need to get any more data, just wrap the value
331                 $(this).html('<textarea>'+data_value+'</textarea>')
332                 .append('<span class="original_data">'+data_value+'</span>');
333                 $(".original_data").hide();
334             }
335             else if($(this).is('.truncated, .transformed')) {
336                 /** @lends jQuery */
337                 //handle truncated/transformed values values
339                 /**
340                  * @var sql_query   String containing the SQL query used to retrieve value of truncated/transformed data
341                  */
342                 var sql_query = 'SELECT ' + field_name + ' FROM ' + window.parent.table + ' WHERE ' + where_clause;
344                 // Make the Ajax call and get the data, wrap it and insert it
345                 $.post('sql.php', {
346                     'token' : window.parent.token,
347                     'db' : window.parent.db,
348                     'ajax_request' : true,
349                     'sql_query' : sql_query,
350                     'inline_edit' : true
351                 }, function(data) {
352                     if(data.success == true) {
353                         $(this_field).html('<textarea>'+data.value+'</textarea>')
354                         .append('<span class="original_data">'+data_value+'</span>');
355                         $(".original_data").hide();
356                     }
357                     else {
358                         PMA_ajaxShowMessage(data.error);
359                     }
360                 }) // end $.post()
361             }
362             else if($(this).is('.relation')) {
363                 /** @lends jQuery */
364                 //handle relations
366                 /**
367                  * @var curr_value  String containing the current value of this relational field
368                  */
369                 var curr_value = $(this).find('a').text();
371                 /**
372                  * @var post_params Object containing parameters for the POST request
373                  */
374                 var post_params = {
375                         'ajax_request' : true,
376                         'get_relational_values' : true,
377                         'db' : window.parent.db,
378                         'table' : window.parent.table,
379                         'column' : field_name,
380                         'token' : window.parent.token,
381                         'curr_value' : curr_value
382                 }
384                 $.post('sql.php', post_params, function(data) {
385                     $(this_field).html(data.dropdown)
386                     .append('<span class="original_data">'+data_value+'</span>');
387                     $(".original_data").hide();
388                 }) // end $.post()
389             }
390             else if($(this).is('.enum')) {
391                 /** @lends jQuery */
392                 //handle enum fields
393                 /**
394                  * @var curr_value  String containing the current value of this relational field
395                  */
396                 var curr_value = $(this).text();
398                 /**
399                  * @var post_params Object containing parameters for the POST request
400                  */
401                 var post_params = {
402                         'ajax_request' : true,
403                         'get_enum_values' : true,
404                         'db' : window.parent.db,
405                         'table' : window.parent.table,
406                         'column' : field_name,
407                         'token' : window.parent.token,
408                         'curr_value' : curr_value
409                 }
411                 $.post('sql.php', post_params, function(data) {
412                     $(this_field).html(data.dropdown)
413                     .append('<span class="original_data">'+data_value+'</span>');
414                     $(".original_data").hide();
415                 }) // end $.post()
416             }
417             else if($(this).is('.null')) {
418                 //handle null fields
419                 $(this_field).html('<textarea></textarea>')
420                 .append('<span class="original_data">NULL</span>');
421                 $(".original_data").hide();
422             }
423         })
424     }) // End On click, replace the current field with an input/textarea
426     /**
427      * After editing, clicking again should post data
428      *
429      * @memberOf    jQuery
430      * @name        inline_edit_save
431      * @see         PMA_ajaxShowMessage()
432      * @see         getFieldName()
433      */
434     $(".edit_row_anchor_active").live('click', function(event) {
435         /** @lends jQuery */
436         event.preventDefault();
438         /**
439          * @var this_row    Object referring to current row that is being edited
440          */
441         var this_row = $(this);
443         // Initialize variables
444         if(disp_mode == 'vertical') {
445             /**
446              * @var this_row_index  Index of the current <td> in the parent <tr>
447              *                      Current <td> is the inline edit anchor.
448              */
449             var this_row_index = $(this).index();
450             /**
451              * @var input_siblings  Object referring to all inline editable events from same row
452              */
453             var input_siblings = $(this).parents('tbody').find('tr').find('.data_inline_edit:nth('+this_row_index+')');
454             /**
455              * @var where_clause    String containing the WHERE clause to select this row
456              */
457             var where_clause = $(this).parents('tbody').find('tr').find('.where_clause:nth('+this_row_index+')').val();
458         }
459         else {
460             var input_siblings = $(this).parent('tr').find('.data_inline_edit');
461             var where_clause = $(this).parent('tr').find('.where_clause').val();
462         }
464         /**
465          * @var nonunique   Boolean, whether this row is unique or not
466          */
467         if($(this).is('.nonunique')) {
468             var nonunique = 0;
469         }
470         else {
471             var nonunique = 1;
472         }
474         // Collect values of all fields to submit, we don't know which changed
475         /**
476          * @var params_to_submit    Array containing the name/value pairs of all fields
477          */
478         var params_to_submit = {};
479         /**
480          * @var relation_fields Array containing the name/value pairs of relational fields
481          */
482         var relation_fields = {};
483         /**
484          * @var transform_fields    Array containing the name/value pairs for transformed fields
485          */
486         var transform_fields = {};
487         /**
488          * @var transformation_fields   Boolean, if there are any transformed fields in this row
489          */
490         var transformation_fields = false;
492         $(input_siblings).each(function() {
493             /** @lends jQuery */
494             /**
495              * @var this_field  Object referring to this field (<td>)
496              */
497             var this_field = $(this);
498             /**
499              * @var field_name  String containing the name of this field.
500              * @see getFieldName()
501              */
502             var field_name = getFieldName($(this), disp_mode);
504             /**
505              * @var this_field_params   Array temporary storage for the name/value of current field
506              */
507             var this_field_params = {};
509             if($(this).is('.transformed')) {
510                 transformation_fields =  true;
511             }
513             if($(this).is(":not(.relation, .enum)")) {
514                 this_field_params[field_name] = $(this).find('textarea').val();
515                 if($(this).is('.transformed')) {
516                     $.extend(transform_fields, this_field_params);
517                 }
518             }
519             else {
520                 this_field_params[field_name] = $(this).find('select').val();
522                 if($(this).is('.relation')) {
523                     $.extend(relation_fields, this_field_params);
524                 }
525             }
527             $.extend(params_to_submit, this_field_params);
528         })
530         /**
531          * @var sql_query   String containing the SQL query to update this row
532          */
533         var sql_query = 'UPDATE ' + window.parent.table + ' SET ';
535         $.each(params_to_submit, function(key, value) {
536             if(value.length == 0) {
537                 value = 'NULL'
538             }
539            sql_query += ' ' + key + "='" + value + "' , ";
540         })
541         //Remove the last ',' appended in the above loop
542         sql_query = sql_query.replace(/,\s$/, '');
543         sql_query += ' WHERE ' + where_clause;
545         /**
546          * @var rel_fields_list  String, url encoded representation of {@link relations_fields}
547          */
548         var rel_fields_list = $.param(relation_fields);
550         /**
551          * @var transform_fields_list  String, url encoded representation of {@link transform_fields}
552          */
553         var transform_fields_list = $.param(transform_fields);
555         // Make the Ajax post after setting all parameters
556         /**
557          * @var post_params Object containing parameters for the POST request
558          */
559         var post_params = {'ajax_request' : true,
560                             'sql_query' : sql_query,
561                             'disp_direction' : disp_mode,
562                             'token' : window.parent.token,
563                             'db' : window.parent.db,
564                             'table' : window.parent.table,
565                             'clause_is_unique' : nonunique,
566                             'where_clause' : where_clause,
567                             'rel_fields_list' : rel_fields_list,
568                             'do_transformations' : transformation_fields,
569                             'transform_fields_list' : transform_fields_list,
570                             'goto' : 'sql.php'
571                           };
573         $.post('tbl_replace.php', post_params, function(data) {
574             if(data.success == true) {
575                 PMA_ajaxShowMessage(data.message);
576                 $(this_row).removeClass('edit_row_anchor_active').addClass('edit_row_anchor');
578                 $(input_siblings).each(function() {
579                     // Inline edit post has been successful.
580                     if($(this).is(':not(.relation, .enum)')) {
581                         /**
582                          * @var new_html    String containing value of the data field after edit
583                          */
584                         var new_html = $(this).find('textarea').val();
586                         if($(this).is('.transformed')) {
587                             var field_name = getFieldName($(this), disp_mode);
588                             var this_field = $(this);
590                             $.each(data.transformations, function(key, value) {
591                                 if(key == field_name) {
592                                     if($(this_field).is('.text_plain, .application_octetstream')) {
593                                         new_html = value;
594                                         return false;
595                                     }
596                                     else {
597                                         var new_value = $(this_field).find('textarea').val();
598                                         new_html = $(value).append(new_value);
599                                         return false;
600                                     }
601                                 }
602                             })
603                         }
604                     }
605                     else {
606                         var new_html = $(this).find('select').val();
607                         if($(this).is('.relation')) {
608                             var field_name = getFieldName($(this), disp_mode);
609                             var this_field = $(this);
611                             $.each(data.relations, function(key, value) {
612                                 if(key == field_name) {
613                                     var new_value = $(this_field).find('select').val();
614                                     new_html = $(value).append(new_value);
615                                     return false;
616                                 }
617                             })
618                         }
619                     }
620                     $(this).html(new_html);
621                 })
622             }
623             else {
624                 PMA_ajaxShowMessage(data.error);
625             };
626         }) // end $.post()
627     }) // End After editing, clicking again should post data
628 }, 'top.frame_content') // end $(document).ready()
630 /**#@- */